这篇文章主要介绍“C++ decltype的使用方法”,在日常操作中,相信很多人在C++ decltype的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++ decltype的使用方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导。引入decltype是因为auto并不适用于所有的自动类型推导场景,在某些特殊情况下auto用起来很不方便,甚至压根无法使用。
对于内置类型的对象,使用decltype很直观,但当参数为复合类型的时候就应该注意一些使用细节问题。
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的几种形式
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 * *
decltype的推导规则可以简单概述如下:
如果exp是一个不被括号()包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,decltype(exp)的类型和exp一致
如果exp是函数调用,则decltype(exp)的类型就和函数返回值的类型一致
如果exp是一个左值,或被括号()包围,decltype(exp)的类型就是exp的引用,假设exp的类型为T,则decltype(exp)的类型为T&
规则1示例:
#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示例:
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示例:
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; }
左值:表达式执行结束后依然存在的数据,即持久性数据;右值是指那些在表达式执行结束不再存在的数据,即临时性数据。一个区分的简单方法是:对表达式取地址,如果编译器不报错就是左值,否则为右值
类的静态成员可以使用auto, 对于类的非静态成员无法使用auto,如果想推导类的非静态成员的类型,只能使用decltype。
示例如下:
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的使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。