auto
所修饰的变量必须进行初始化,这是它的一个局限性。而 decltype
用来在编译时推导出一个表达式的类型。语法:decltype(exp)
。
decltype
的推导规则。
主要有三个推导规则:
- exp 是标识符、访问表达式,
decltype(exp)
和 exp 的类型一致; - exp 是函数调用,
decltype(exp)
和返回值的类型一致; - 如果表达式是左值(lvalue),
decltype
返回左值引用类型;如果是右值(rvalue),decltype
返回该表达式的原始类型。
下面看一些例子以便更容易理解上面推导规则的含义。
应用场景
- 推断变量的类型
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
#define TO_STRING(x) #x
int main()
{
int x = 0;
decltype(x) y = 1; // y 的类型是 int
decltype((x)) z = x; // z 的类型是 int&
cout << "变量 " << TO_STRING(a) << " 的类型是int: " << (typeid(y) == typeid(int)) << endl;
cout << "变量 " << TO_STRING(z) << " 的类型是int&: " << (typeid(z) == typeid(int&)) << endl;
z = 100;
cout << "z is " << z << endl;
cout << "x is " << x << endl;
int &a = x;
decltype(a) b = x; // b 的类型是 int&
cout << "变量 " << TO_STRING(b) << " 的类型是int&: " << (typeid(b) == typeid(int&)) << endl;
const int m_cint = 1;
const int &n = m_cint;
decltype(n) q = n; // q 的类型是const int&
decltype(m_cint) s = 10; // s 的类型是 const int
cout << "变量 " << TO_STRING(s) << " 的类型是const int: " << (typeid(s) == typeid(const int)) << endl;
cout << "变量 " << TO_STRING(q) << " 的类型是const int&: " << (typeid(q) == typeid(const int&)) << endl;
int *p = &x;
decltype(p) ptr1 = p; // ptr1的类型是int*
cout << "变量 " << TO_STRING(ptr1) << " 的类型是int*: " << (typeid(ptr1) == typeid(int*)) << endl;
return 0;
}
执行结果:
变量 a 的类型是int: 1
变量 z 的类型是int&: 1
z is 100
x is 100
变量 b 的类型是int&: 1
变量 s 的类型是const int: 1
变量 q 的类型是const int&: 1
变量 ptr1 的类型是int*: 1
- 推断函数返回值:
int func();
decltype(func()) var; // var 的类型与 func() 的返回类型相同
- 推断类成员的类型
class Foo
{
public:
static const int number = 0;
int x;
};
decltype(Foo:number) c = 0; // c -> const int
Foo foo;
decltype(foo.x) d = 0; // d -> int, 类访问表达式
- 返回类型后置——auto 和 decltype 的结合使用
int& foo(int& i);
float foo(float& f);
template<typename T>
auto func(T& val) -> decltype(foo(val))
{
return foo(val);
}
好了,以上就是 decltype
关键的常见用法。如有收获,点个赞再走也不迟。