仅供复习和查看用途,欢迎各位进行友善的讨论交流
item 1:理解模板型别推导
模板和调用的一般形式
template<typename T>
void f(ParamType param);
f(expr); // 根据expr推导T和ParamType
T的型别推导不仅依赖于expr,还依赖于ParamType,具体如下
情况1:ParamType为指针或引用,型别推导的运作
1)若expr具有引用型别,忽略引用(如果实参是引用,在这种情况下引用性会被忽略掉)
2)对expr和ParamType的型别进行匹配,来决定T的型别
template<typename T>
void f(const T ¶m);
int x =0;
const int cx = x;
//由于假定param具有const引用,T的型别推到中含有const也就没有必要了
f(x); //T:int ,param:const int&
f(cx); //T:int, param:const int&
情况2:ParamType是万能引用
1)如果为左值,T和ParamType都会推到为左值引用(T被推导为型别的唯一情形)
2)如果expr为右值,对用情况1;
template<typename T>
void f(T &¶m);
int x =0;
const int cx = x;
//由于假定param具有const引用,T的型别推到中含有const也就没有必要了
f(x); //T:int& ,param:int&
f(cx); //T:const int&, param:const int&
情况3:ParamType既不是指针也非引用
1)若expr具有引用型别,忽略引用
2)忽略引用性之后,const和volatile也忽略之
试着考虑这种情形:
const char * const ptr = "hello world";
f(ptr); //哪一个const会被挥发掉?顶层const表示指针本身是个常量,底层const表示所指的对象是常量
数组实参和函数实参
template<typename T>
void f(T param);//T推导成const char *
或者
template<typename T>
void f(T ¶m);//T推导成const char [N]
template <typename T, size_t N>
constexpr size_t ArraySize(T (&)[N]) noexcept{
cout<< "size:"<<N<<endl; //输出size:6
}
int main ()
{
const char ptr[] = "hello";
ArraySize(ptr);
return 0;
}
小结
- 模板推导中,引用性会被忽略
- 万能引用形参推导时,左值进行特殊处理(引用折叠)
- 按值传递形参,忽略const和volatile
- 数组和函数型别的实参退化为对应的指针,除非被用来初始化引用
item 2:理解auto推导
在一般情况下,auto型别推导和模板推导是一样的,但是auto推导会假定使用大括号的初始化表达式是std::initializer_list
// 这里会发生两种推导,第一种源于auto的使用,x需要推导为std::initializer_list,
// 但由于是模板类,需要根据某个型别T产生实例对象,std::initializer_list<T>意味着
// T也必须被推导出来,进行二级推导
auto x = {1, 2, 3 };
由于模板只能进行一级推导,因此下面代码推导失败
template<typename T>
void f(T param); // 若指定为std::initializer_list<T> 则可以通过编译
f({1, 2, 3});
以上是关于c++11的auto内容,对于c++14使用auto来说明函数返回值需要推导,以及lambda表达式也会在形参中使用auto,这些用法是在使用模板推导而非auto推导(也就是只能进行一级推导)
item 3:理解decltype
// 万能引用搭配std::forward(相对于右值引用搭配std::move)
template<typename Container, typename Index>
decltype(auto) //c++14 ,c++11使用尾置返回
func(Container && c, Index i){
...
return std::forward<Container>(c)[i];
}
特殊情况:只要左值表达式不仅是一个型别为T的对象,就得出一个T&
int x = 0; // decltype(x) : int, decltype((x)) : int&