【C++ Primer Chapter 2 总结】decltype & auto
decltype gives the declared type of the expression that is passed to it.
auto does the same thing as template type deduction.
So, for example, if you have a function that returns a reference, auto will still be a value (you need auto& to get a reference),
but decltype will be exactly the type of the return value.
decltype给出其修饰的表达式的类型,auto作用与template类型推断类似。
例如:函数返回值是引用,auto仍然返回的是值本身,因此需要使用 auto& 来获得该引用。 而decltype推断出来的直接是该返回值的类型:引用。
#include <iostream> int global{}; int& foo(){ return global; } int main(){ decltype(foo()) a = foo(); //a is an `int&` auto b = foo(); //b is an `int` b = 2; std::cout << "a: " << a << '\n'; //prints "a: 0" std::cout << "b: " << b << '\n'; //prints "b: 2" decltype(foo()) c = foo(); //c is an `int&` c = 10; std::cout << "---\n"; std::cout << "a: " << a << '\n'; //prints "a: 10" std::cout << "b: " << b << '\n'; //prints "b: 2" std::cout << "c: " << c << '\n'; //prints "c: 10" auto& d = foo(); d = 5; std::cout << "---\n"; std::cout << "a: " << a << '\n'; //prints "a: 5" std::cout << "b: " << b << '\n'; //prints "b: 2" std::cout << "c: " << c << '\n'; //prints "c: 5" std::cout << "d: " << d << '\n'; //prints "d: 5" }
多维数组:
int a[3][4]; for(auto& row : a) { // row的类型: int (&row) [4]; row是大小为4的数组的引用。如果这里是auto row,会编译错误。 因为auto row推断出来的row是int*类型(数组类型会自动转换为指向第一个元素的指针),但是指针类型无法使用for遍历 for(auto& col : row) { // col的类型: int &col; col = cnt; ++cnt; } }
1.auto通常忽视top-level const,保留low-level const。
int i = 0; const int ci = i, &cr = ci; auto b = ci; // b is an int, top=level in ci is dropped auto c = cr; // c in an int, cr is an alias for ci whose const is top-level auto d = &i; // d is an int*, & of an int object is int* auto e = &ci; // e is an const int*, & of a const object is low-level const //如果想要推理出来的类型有top-level const,需要显示说明: const auto f = ci;
2.decltype处理top-level const和引用的方式与auto不同。
当应用decltype的表达式是一个变量时,decltype返回该变量的类型,包括top-level const和引用。
当应用decltype的表达式不是变量时,decltype返回该表达式产生的类型。表达式产生可以作为赋值语句左值的对象时,decltype返回引用类型。
decltype解引用操作的表达式(lvalue)得到的是引用类型。
将变量包装在一组或多组括号中,则编译器会将操作数视为表达式。变量是一个表达式,可以是赋值的左侧,在这样的表达式上的decltype得到引用类型。
const int ci = 0, &cj = ci; decltype(ci) x = 0; // x has type const int cecltype(cj) y = x; // y has type const int& and is bound to x decltype(cj) z; // error: z is a reference and must be initialized int i = 42, *p = &i, &r = i; decltype(r+0) b; // addition yields an int (rvalue) decltype(*p) c; // error: *p yields lvalue, so c is int& and must be initialized decltype((i)) d; // error: (i) is an expression, i is lvalue, so d is int& and must be initialized decltype(i) e; // i is int;