类型推导
条款1:理解模板类型推导
当一个复杂系统的用户忽略其如何工作时,他们依然会对其所做的工作感兴趣,也就是很多关于系统的设计。如果按照这样的标准,模板类型推导算得上c++一个巨大的成功。数百万的c++程序员把参数传给模板函数,获得满意的结果,他们中的很多人甚至给不出传给那些函数的类型是如何推导的最模糊的解释。
如果这些人中有你,那么我有一个好消息和坏消息。好消息是模板的类型推导是现代c++中引人入胜的特征之一–auto的基础。假如你喜欢c++98中的模板类型推导,那你也会喜欢c++11用auto来进行的类型推导。坏消息是当模板的类型推导规则应用于auto场景时,有时候没有像应用在模板上那么直接明显。为此,真正了解模板类型推导是非常重要的,这是auto的建立基础。本条款就覆盖了你所需要了解的。
如果你想先大致了解下伪代码,我们可以看到如下的函数模板:
template
void f(ParamType param);
调用类似这样:
f(expr); // call f with some expression
在编译过程中,编译器会用expr去推导两个类型:一个是T,一个是ParamType。这两个类型通常不一样的,因为ParamType经常包括一些修饰,比如const或者引用。比如,模板可以这样声明,
template
void f(const T& param); // ParamType is const T&
我们这样调用,
int x = 0;
f(x); //call f with an int
T被推导成int,但是ParamType被推导成const int& 。
我们很自然的期望对T的类型推导和传递给函数的参数类型一样,就是说T就是expr的类型。在上面例子中,情况就是x是个int,于是T被推导为int。但情况并不总是这样,T的类型推导并不仅依赖于expr的类型,还会依赖于ParamType的形式。有3种情况:
1.ParamType是一个指针或引用 ,但不是统一引用(universal reference)(统一引用将在条款24中描述,此时你只要知道,它是左值或右值引用都不同)。
2.ParamType是个统一引用。
3.ParamType既不是指针也不是引用。
因此我们需要验证3种类型推导的场景,每一种都基于我们通用的模板形式和调用:
template
void f(ParamType param);
f(expr); // deduce T and ParamType from expr
场景1:ParamType是一个指针或引用 ,但不是统一引用
最简单的情况就是ParamType是一个引用类型或指针类型,但不是一个统一引用。这种情况下类型推导的工作原理如下:
1.如果expr类型是一个引用,忽略引用部分。
2.expr的类型和ParamType模式匹配的部分决定了T。
比如这样的模板,
template
void f(T& param); // param is a reference
我们的变量声明是这样的,
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
各种变量对ParamType和T的推导出的类型如下,
f(x); // T is int, param’s ty
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
