auto
话说C语言还处于K&R时代,也有auto a = 1;的写法。中文译过来叫自动变量,跟c++11的不同,C语言的auto a = 1;相当与 auto int a = 1;语句。 而C++11的auto是有着严格的类型推导出来的。以前是这么写
int a = 1;
现在,编译器知道a是int型了。所以可以这么写
auto a = 1;
对于类型比较长的,如vector<string>::iterator这类的,能少敲些字符了。
如果仅仅就这点作用,那么对编程实在没什么太大的益处,虽然自动类型推导对于编译器而言,是个高大上的话题。实际上,作用远远不止这点啊。适当地使用auto,会是你的代码更优雅,举例说明:
template <typename BuiltType, typename Builder>
void makeAndProcessObject (const Builder& builder)
{
BuiltType val = builder.makeObject();
// do stuff with val
}
void makeAndProcessObject (const Builder& builder)
{
BuiltType val = builder.makeObject();
// do stuff with val
}
从这代码来看,BuiltType的用处不大,但必须这么写才能编译过。有了auto后,你可以这么写
template <typename Builder>
void makeAndProcessObject(const Builder& builder)
{
auto val = builder.makeObject();
// do stuff with val
}
这比上段代码就优雅些了。可是如果我要返回val的值呢?我们还是要传入BuildTye,因为_______________(现在我也不知道为什么需要返回类型后置,难道不能靠返回值来推导?如果有清楚的朋友不妨告诉我)。
在看一遍auto a = 1;表达式。发现自动类型推导具有这样的特点:它可以先不必知道是什么类型,而是根据后面的信息来推导。如果我们能把返回类型先用auto代替,然后在给些信息让编译器推导出来,这就需要派上decltype了。
decltype
decltype意为declared Type,即声明类型。decltype(x)表示从x中提取类型。因此,可以这样写:
decltype(x) y = x;
当然,x也可以换成一个表达式,decltype(builder.makeObject())将得到makeObject()返回的类型。如果我们结合auto和decltype就可以写出如下代码:
template <typename Builder>
auto makeAndProcessObject(const Builder& builder) -> decltype(builder.makeObject())
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
这就是返回类型后置。从上面的例子可以看出,decltype对于模板编写会有所帮助。如果不用自己写模板的话,或许用的并不多。
decltype这个特性,BS在2002年就提议标准化这类操作符了。gcc c++编译器于2008加入该特性,visual c++ 2010以扩展形式提供了该特性,到c++11才加入标准。而普及到大众程序员的时间大概是2013前后吧。可见,技术的发展或许快,然而这只是局部性的。要普及到大众,速度就有点慢了。想想人生真正奋斗的时间也就短短几十年,推广普及一个技术,真要消耗人的一生光阴。现在的BS已经是白发苍苍矣。