1.什么是decltype
decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导。引入decltype是因为auto并不适用于所有的自动类型推导场景,在某些特殊情况下auto用起来很不方便,甚至压根无法使用。
对于内置类型的对象,使用decltype很直观,但当参数为复合类型的时候就应该注意一些使用细节问题。
1
2
|
auto varName=value;
decltype( exp ) varName=value;
|
- auto根据=右边的初始值推导出变量的类型,decltype根据exp表达式推导出变量的类型,跟=右边的value没有关系
- auto要求变量必须初始化,这是因为auto根据变量的初始值来推导变量类型的,如果不初始化,变量的类型也就无法推导
- 而decltype不要求,因此可以写成如下形式
decltype(exp) varName;
原则上将,exp只是一个普通的表达式,它可以是任意复杂的形式,但必须保证exp的结果是有类型的,不能是void;如exp为一个返回值为void的函数时,exp的结果也是void类型,此时会导致编译错误
1.1decltype的几种形式
1
2
3
4
5
6
7
8
|
int x = 0;
decltype(x) y = 1; // y -> int
decltype(x + y) z = 0; // z -> int
const int & i = x;
decltype(i) j = y; // j -> const int &
const decltype(z) * p = &z; // *p -> const int, p -> const int *
decltype(z) * pi = &z; // *pi -> int , pi -> int *
decltype(pi)* pp = π // *pp -> int * , pp -> int * *
|
2.推导规则
decltype的推导规则可以简单概述如下:
- 如果exp是一个不被括号()包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,decltype(exp)的类型和exp一致
- 如果exp是函数调用,则decltype(exp)的类型就和函数返回值的类型一致
- 如果exp是一个左值,或被括号()包围,decltype(exp)的类型就是exp的引用,假设exp的类型为T,则decltype(exp)的类型为T&
规则1示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include<string>
#include<iostream>
using namespace std;
class A{
public :
static int total;
string name;
int age;
float scores;
}
int A::total=0;
int main()
{
int n=0;
const int &r=n;
A a;
decltype(n) x=n; //n为Int,x被推导为Int
decltype(r) y=n; //r为const int &,y被推导为const int &
decltype(A::total) z=0; ///total是类A的一个int 类型的成员变量,z被推导为int
decltype(A.name) url= "www.baidu.com" ; //url为stringleix
return 0;
}
|
规则2示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int & func1( int , char ); //返回值为int&
int && func2( void ); //返回值为int&&
int func3( double ); //返回值为int
const int & func4( int , int , int ); //返回值为const int&
const int && func5( void ); //返回值为const int&&
int n=50;
decltype(func1(100, 'A' )) a=n; //a的类型为int&
decltype(func2()) b=0; //b的类型为int&&
decltype(func3(10.5)) c=0; //c的类型为int
decltype(func4(1,2,3)) x=n; //x的类型为const int&
decltype(func5()) y=0; //y的类型为const int&&
|
exp中调用函数时需要带上括号和参数,但这仅仅是形式,并不会真的去执行函数代码
规则3示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class A{
public :
int x;
}
int main()
{
const A obj;
decltype(obj.x) a=0; //a的类型为int
decltype((obj.x)) b=a; //b的类型为int&
int n=0,m=0;
decltype(m+n) c=0; //n+m得到一个右值,c的类型为int
decltype(n=n+m) d=c; //n=n+m得到一个左值,d的类型为int &
return 0;
}
|
左值:表达式执行结束后依然存在的数据,即持久性数据;右值是指那些在表达式执行结束不再存在的数据,即临时性数据。一个区分的简单方法是:对表达式取地址,如果编译器不报错就是左值,否则为右值
3.实际应用
类的静态成员可以使用auto, 对于类的非静态成员无法使用auto,如果想推导类的非静态成员的类型,只能使用decltype。
示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
template < typename T>
class A
{
private :
decltype(T.begin()) m_it;
//typename T::iterator m_it; //这种用法会出错
public :
void func(T& container)
{
m_it=container.begin();
}
};
int main()
{
const vector< int > v;
A< const vector< int >> obj;
obj.func(v);
return 0;
}
|
到此这篇关于C++ decltype用法举例说明的文章就介绍到这了,更多相关C++ decltype内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/qq_38196982/article/details/118578967