c++ decltype关键字
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)() 这句代码构造了该迭代器类型的默认初始化对象。