新的返回值语法和类型获取(Decltype)语句
在原来,我们声明一个函数都是这样的:
int temp(int a, double b);
前面那个int是函数的返回值类型,temp是函数名,int a, double b是参数列表。
现在你可以将函数返回值类型移到到参数列表之后来定义:
auto temp(int a, double b) -> int;
后置返回值类型可以有很多用处。比如有下列的类定义:
class Person
{
public:
enum PersonType { ADULT, CHILD, SENIOR };
void setPersonType (PersonType person_type);
PersonType getPersonType ();
private:
PersonType _person_type;
};
那么在定义getPersonType函数的时候我们得这么写:
Person::PersonType Person::getPersonType ()
{
return _person_type;
}
因为函数所在的类Person是声明在函数返回值之后的,所以在写返回值的时候编译器并不知道这个函数是在哪个类里面。由于PersonTYpe是Person类的内部声明的枚举,所以在看到PersonType的时候,编译器是找不到这个类型的。所以你就得在PersonTYpe前面加上Person::,告诉编译器这个类型是属于Person的。这看起来有点麻烦是吧。当你使用新的返回值语法的时候呢就可以这么写:
auto Person::getPersonType () -> PersonType
{
return _person_type;
}
因为这次编译器看到返回值类型PersonType的时候已经知道这个函数属于类Person。所以它会到Person类中去找到这个枚举类型。
当然上述应用只能说是一个奇技淫巧而已。并没有帮我们多大的忙(代码甚至都没有变短)。所以还得引入C++11的另一个功能。
类型获取(Decltype)
既然编译器能够推断一个变量的类型,那么我们在代码中就应该能显示地获得一个变量的类型信息。所以C++介绍了另一个功能:decltype。(实在是不知道这个词该怎么翻译,姑且称之为类型获取)。
int x = 3;
decltype(x) y = x; // same thing as auto y = x;
上述代码就使用了类型获取功能。和函数返回值后置语法结合起来,可以有如下应用:
template
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
{
auto val = builder.makeObject();
// do stuff with val
return val;
}
前面的例子中这个函数的返回值是void,所以不需要为返回值引入泛型。如果返回值是makeObject的返回值的话,那么这个函数就得引入两个泛型。现在又了类型获取功能,我们就能在返回值中自动推断makeObject的类型了。所以decltype确实为我们提供了很大的便利。
这个功能非常重要,在很多时候,尤其是引入了泛型编程的时候,你可能记不住一个变量的类型或者类型太过复杂以至于写不出来。你就要灵活使用decltype来获取这个变量的类型。
自动类型推断在Lambda表达式(匿名函数)中的作用