decltype为类型推导关键字。 示例代码:
// decltype也可用于函数模板编程:
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
// decltype推导函数返回类型
auto doubleNumFunc(int x) -> decltype(x * 2) {
return x * 2;
};
// 测试decltype关键字的各种用法
void testDecltype() {
// 基本用法
int x;
decltype(x) y = 10;
auto& typeInfoY = typeid(y);
cout << "type y: " << typeInfoY.name() << endl;
// 推导表达式类型
struct MyStruct
{
size_t sum(size_t a, size_t b) {
cout << a << " + " << b << " = " << (a + b) << endl;
return a + b;
}
};
MyStruct myStruct;
decltype(myStruct.sum(1, 2) / 0) z; // 这里直接推导类型,不会调用函数,也不会计算值,所以除0也不报错。
auto& typeInfoZ = typeid(z);
cout << "type z: " << typeInfoZ.name() << endl;
// 引用类型的推导
unsigned m = 0;
unsigned& n = m;
decltype(n) a = m; // 因为a是引用类型,所以这里必须赋值,否则报错:引用变量a需要初始值设定项
auto& typeInfoA = typeid(a);
cout << "type a: " << typeInfoA.name() << endl;
// 调用模板函数
auto b = add(1, 2.5);
auto& typeInfoB = typeid(b);
cout << "type b: " << typeInfoB.name() << endl;
auto c = doubleNumFunc(1);
auto& typeInfoC = typeid(c);
cout << "type c: " << typeInfoC.name() << endl;
}
打印:
ok. 意犹未尽,再结合类模板测试下。代码如下:
template <typename T> // T为容器类
class TestDecltype {
public:
auto getIterator(T& container) -> decltype(container.begin()) {
if (iterator == decltype(iterator)()) { // 迭代器与默认构造迭代器比较,而不能直接与nullptr比较或赋值(!iterator 这样编译不过)
iterator = container.begin();
}
return iterator;
}
TestDecltype():iterator(){}
private:
decltype(T().begin()) iterator; // 这里推导了迭代器的类型,这里是默认构造,没有真正关联到具体容器数据呢。
};
void testDecltype2() {
vector<int> vec{9, 5, 2, 7};
TestDecltype<vector<int>> demo;
for (auto it = demo.getIterator(vec); it != vec.end(); it++) {
cout << *it << " ";
}
std::cout << std::endl;
}
打印:
ok. 注意,getIterator函数中,decltype(iterator)() 这句代码构造了该迭代器类型的默认初始化对象。