You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
type specifier是一个指针或者引用,但不是universal reference(或者叫forwarding references).
type specifier是一个universal reference。
type specifier既不是指针也不是引用。
Case 1 : type specifier是一个指针或者引用,但不是universal reference
constauto& rx = x;
上面分析过,不再赘述。
Case 2 : type specifier是一个universal reference
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int&auto&& uref3 = 27; // 27 is int and rvalue, so uref3's type is int&&
int x = 50;
int &f() { return x; }
intmain() {
auto a1 = f();
a1 = 10; // x = 50auto &a2 = f();
a2 = 20; // x = 20return0;
}
数组和函数类型推断
在函数模板参数推断中讨论了数组和函数作为模板参数的推断情况,在auto类型推断中情况也是相同的:
constchar name[] = "R. N. Briggs";
auto arr1 = name; // arr1's type is const char*auto& arr2 = name; // arr2's type is const char (&)[13]
voidsomeFunc(int, double);
auto func1 = someFunc; // func1's type is void (*)(int, double)auto& func2 = someFunc; // func2's type is void (&)(int, double)
auto与函数模板参数推断的区别
从C++11起有4种选择可以定义一个整形变量:
auto x1 = 27;
autox2(27);
auto x3 = { 27 };
auto x4{ 27 };
auto x1 = 27; // type is int, value is 27autox2(27); // type is int, value is 27auto x3 = { 27 }; // type is std::initializer_list<int>, value is { 27 }auto x4{ 27 }; // type is std::initializer_list<int>, value is { 27 }
template<typename T>
voidf(std::initializer_list<T> initList);
f({ 11, 23, 9 }); // T deduced as int, and initList's type is std::initializer_list<int>
上篇文章讲了模板参数的推导规则,其实auto的推导规则跟模板参数的推导基本上一样的,都是推导参数嘛。比如上篇文章的模板基本结构是:
编译器使用expr来推断
ParamType
和T
。那么对应在auto推导中,auto就对应了
T
,变量的type specifier
就是ParamType
:这里,cx的
type specifier
就是const auto
,rx的type specifier
就是const auto&
.我们可以想象成在推导auto类型时,编译器就是在做一次模板参数类型推断:
在模板参数推导中,我们根据
ParamType
将情况分成了三类。在auto推导中,我们同样可以根据type specifier
来分成三种情况:type specifier
是一个指针或者引用,但不是universal reference(或者叫forwarding references).type specifier
是一个universal reference。type specifier
既不是指针也不是引用。Case 1 : type specifier是一个指针或者引用,但不是universal reference
上面分析过,不再赘述。
Case 2 : type specifier是一个universal reference
Case 3 : type specifier既不是指针也不是引用
注意这个Case的情况,假如我们有个函数返回引用,我们使用auto接收返回值,如果我们想改变函数的返回值,那么必须用auto&,而不是auto,因为这里和函数模板参数推断规则一样,是pass-by-value,会忽略引用、const和volatile:
数组和函数类型推断
在函数模板参数推断中讨论了数组和函数作为模板参数的推断情况,在auto类型推断中情况也是相同的:
auto与函数模板参数推断的区别
从C++11起有4种选择可以定义一个整形变量:
最后两种是C++11的新特性:统一初始化(uniform initialization),就是这个造成了模板参数推导和auto类型推导的最大区别 :
特殊点在于:如果使用
uniform initialization
来进行auto类型推断,那么最终auto推断出的结果是std::initializer_list<int>
所以下面的代码会编译报错:
但是如果指定
ParamType
为std::initializer_list<T>
,则可以正确的推断T的类型:C++14中更特殊的情况
在C++14中,允许将函数返回值和lambda参数声明为auto,但是在这种情况下,auto的类型推断使用的是模板参数类型推断规则:
(完)
朋友们可以关注下我的公众号,获得最及时的更新:
The text was updated successfully, but these errors were encountered: