C++ operator关键字的使用(重载运算符、仿函数、类型转换操作符)
C++11实用技术(一)auto与decltype的使用
C++11实用技术(二)std::function和bind绑定器
C++11实用技术(三)std::future、std::promise、std::packaged_task、async
C++11引入了两个关键字用于类型推导:auto和decltype。两个关键字的用法有所不同,可以在不同场景中应用,也可以结合使用在某些场景中。
auto和decltype是在编译时推导确认变量类型,所以也不会影响性能。
auto推导的变量必须被初始化。因为编译器需要通过初始化来确定auto所代表的类型、即需要定义变量。
auto x = 5; //x被推导为int类型
auto s; //错误,auto无法推导没有被初始化的s的类型。
auto s = x; //s被推导为和x一样的int类型
auto在一些STL容器中有比较好的用武之地。特别是迭代器的遍历,例如:
#include
int main()
{
std::map<double, double> mp;
;
for(std::map<double, double>::iterator it = mp.begin(); it != mp.end(); ++it)
{
//处理it内容
}
return 0;
}
应用auto做类型推导
#include
int main()
{
std::map<double, double> mp;
;
for(auto it = mp.begin(); it != mp.end(); ++it)
{
//处理it内容
}
return 0;
}
可以看出使用auto后,代码简洁了许多。
刚刚提到auto在推导变量类型时,所修饰的变量必须初始化。那不需要初始化的场景就需要使用到decltype关键字来做类型推导。
例如:
int x = 0;
decltype(x) y; //y 被推导为int类型
decltype (x + y) z = 0;//变量 z 被推导为 int 类型,通过使用 decltype 推导 x + y 的结果类型,并将其初始化为 0。
decltype通常应用在泛型编程中。例如常见模板类:
template <class ContainerT>
class Foo
{
public:
void func(ContainerT& container)
{
it_ = container.begin();
}
private:
decltype(ContainerT().begin()) it_;
};
template <typename T, typename U>
decltype(t + u) add(T t, U u) //错误, t,u在推导的时候还没有被定义
{
return t + u;
}
这段代码编译不过,因为t,u在参数列表中,C++的返回值是前置语法,这里先推导返回值类型是找不到u,t的定义。
可以修改为返回类型后置语法:
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u)//可以编译通过
{
return t + u;
}
这也是auto、decltype最常用的组合用法。
进一步举例,decltype推导函数返回值也可以:
int& foo(int& i);
float foo(float& f);//这里是foo重载
template <typename T>
auto func(T& val) -> decltype(foo(val))
{
return foo(val);
}