大佬教程收集整理的这篇文章主要介绍了C++ decltype(类型推导)精讲,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
decltype(exp)
其中,exp 表示@L_450_1@表达式(expression)。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 * *对代码的说明:
const decltype(z)*p
推导出来的其实是 *p 的类型(const int),然后再进一步运算出 p 的类型。
class Foo { public: static const int number = 0; int x; }; int n = 0; volatile const int & x = n; decltype(n) a = n; // a -> int decltype(X) b = n; // b -> const volatilE int & decltype(Foo::number) c = 0; // c -> const int Foo foo; decltype(foo.X) d = 0; // d -> int,类访问表达式变量 a、b、c 保留了表达式的所有属性(cv、引用)。这里的结果是很简单的,按照推导规则1,对于标识符表达式而言,decltype 的推导结果就和这个变量的类型定义一致。
int& func_int_r(void); // 左值(lvalue,可简单理解为可寻址值) int&& func_int_rr(void); // x值(xvalue,右值引用本身是@L_450_1@xvalue) int func_int(void); // 纯右值(prvalue,将在后面的章节中讲解) const int& func_cint_r(void); // 左值 const int&& func_cint_rr(void); // x值 const int func_cint(void); // 纯右值 const Foo func_cfoo(void); // 纯右值 // 下面是测试语句 int x = 0; decltype(func_int_r()) a1 = x; // a1 -> int & decltype(func_int_rr()) b1 = 0; // b1 -> int && decltype(func_int()) c1 = 0; // c1 -> int decltype(func_cint_r()) a2 = x; // a2 -> const int & decltype(func_cint_rr()) b2 = 0; // b2 -> const int && decltype(func_cint()) c2 = 0; // c2 -> int decltype(func_cfoo()) ff = Foo(); // ff -> const Foo可以看到,按照推导规则2,decltype 的结果和函数的返回值类型保持一致。
warning: type qualif?iers ignored on function return type [-Wignored-qualifiers] cint func_cint(void);
因此,decltype 推导出来的 c2 是@L_450_1@ int。struct Foo { int x; }; const Foo foo = Foo(); decltype(foo.X) a = 0; // a -> int decltype((foo.X)) b = a; // b -> const int & int n = 0,m = 0; decltype(n + m) c = 0; // c -> int decltype(n += m) d = c; // d -> int &a 和 b 的结果:仅仅多加了一对括号,它们得到的类型却是不同的。
#include <vector> template <class ContainerT> class Foo { typename ContainerT::iterator it_; // 类型定义可能有问题 public: void func(ContainerT& container) { it_ = container.begin(); } // ... }; int main(void) { typedef const std::vector<int> container_t; container_t arr; Foo<container_t> foo; foo.func(arr); return 0; }单独看类 Foo 中的 it_ 成员定义,很难看出会有什么错误,但在使用时,若上下文要求传入@L_450_1@ const 容器类型,编译器马上会弹出一大堆错误信息。
template <class ContainerT> class Foo<const containerT> { typename ContainerT::const_iterator it_; public: void func(const containerT& container) { it_ = container.begin(); } // ... };这实在不能说是@L_450_1@好的解决办法。若 const 类型的特化只是为了配合迭代器的类型限制,Foo 的其他代码也不得不重新写一次。
template <class ContainerT> class Foo { decltype(ContainerT().begin()) it_; public: void func(ContainerT& container) { it_ = container.begin(); } // ... };是不是舒服很多了?
vector<int> v; // ... decltype(v)::value_type i = 0;在冗长的代码中,人们往往只会关心变量本身,而并不关心它的具体类型。比如在上例中,只要知道v是@L_450_1@容器就够了(可以提取 value_type),后面的所有算法内容只需要出现 v,而不需要出现像vector<int> 这种精确的类型名称。这对理解一些变量类型复杂但操作统一的代码片段有很大好处。
typedef decltype(nullptr) nullptr_t; //通过编译器关键字nullptr定义类型nullptr_t typedef decltype(sizeof(0)) size_t;这种定义方法的好处是,从类型的定义过程上就可以看出来这个类型的含义。
以上是大佬教程为你收集整理的C++ decltype(类型推导)精讲全部内容,希望文章能够帮你解决C++ decltype(类型推导)精讲所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。