std::decay:
// decay example#include#include typedef std::decay ::type A; // inttypedef std::decay ::type B; // inttypedef std::decay ::type C; // inttypedef std::decay ::type D; // inttypedef std::decay ::type E; // int*typedef std::decay ::type F; // int(*)(int)typedef std::decay ::type G; //int*int main() { std::cout << std::boolalpha; std::cout << "typedefs of int:" << std::endl; std::cout << "A: " << std::is_same ::value << std::endl; //输出均为:true. std::cout << "B: " << std::is_same ::value << std::endl; std::cout << "C: " << std::is_same ::value << std::endl; std::cout << "D: " << std::is_same ::value << std::endl; std::cout << "E: " << std::is_same ::value << std::endl; std::cout << "F: " << std::is_same ::value << std::endl; std::cout << "G: " << std::is_same ::value << std::endl; return 0;}
decltype:
1,它并不会真正运行传入的表达式(unevalueted expression)。
2, 如果传入的 表达式(expression)/变量名 是没有用圆括号扩住的(unparenthesized ,那么我们获取到的是只是该变量初次被声明的类型(这一点体现在class member data access 因为我们可能 const className& value).
3, 如果我们传入的 表达式(expression)/变量名 是用圆括号扩住的(parenthesized , 那么我们获取到的就是它的实际(返回的)类型.
4, 针对unparenthesized expression情况
1) 如果传入的expression返回的是一个 xvalue,那么decltype获取到的类型为 T&&.
2) 如果传入的expression返回的是一个 lvalue,那么decltype获取到的类型为 T&.
3) 如果传入的expression返回的是一个 xvalue,那么decltype获取到的类型为 T.
5, 如果传入decltype的表达式是一个函数调用(function call), 且该函数接受参数,该函数所接受的参数必须是complete type, 但是该函数可以使incomplete type.
6, C++17 structed-binding和decltype(待续).
语法:
decltype ( entity ) (1) (since C++11)decltype ( expression )
demo1:
#include#include //均是在vs2015上面测试的.struct A { int number; A(const int& num) :number(num) {} A() = default; void set_value(const int& n) { this->number = n; } void set_val(const int& n)const { //this->number = n; //error. }};struct B { int* ptr; B(const int& num) :ptr(new int(num)) {} ~B() { delete ptr; ptr = nullptr; } void set_value(const int& n) { *(this->ptr) = n; } void set_val(const int& n)const { if (this->ptr != nullptr) { //delete ptr; //this->ptr = new int(n); //error, 不能修改地址. *(this->ptr) = n; //ok,可以修改值. } }};struct C { int number; int* ptr; C(const int& num, const int& n) :number(num), ptr(new int(n)) {} ~C() { delete ptr; ptr = nullptr; } void print()const { std::cout << std::boolalpha << std::is_same ::value << " \n" << std::is_same ::value << std::noboolalpha << std::endl; }};int n1 = 10;int&& n2 = 10;const int n3 = 10;const int& n4 = 10;int main(){ A* a = new A(20); const A a_(20); //a_.set_value(20); //error. const A& _a = A(20); //_a.set_value(20); //error. const A* ca = new A(20); //ca->set_value(20); //error. B* b = new B(20); const B b_(20); const B& _b = B(20); const B* cb = new B(20); C c(20, 20); std::cout << std::boolalpha << std::is_same ::value << " \n" //输出都为:true. << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ::value << " \n" //注意下面的这些变量有些虽然是不可以修改的,但是仍然不显示const. << std::boolalpha << std::is_same number)>::value << " \n" << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ptr)>::value << " \n" << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ::value << " \n" << std::boolalpha << std::is_same ptr)>::value << " \n"; std::cout << std::endl; std::cout << std::is_same number))>::value << "\n" << std::is_same ::value << "\n" << std::is_same ::value << '\n' << std::is_same ptr))>::value << '\n' << std::is_same ::value << '\n' << std::is_same ::value << '\n' << std::is_same ptr))>::value << '\n'; //c.print(); delete a; delete b; delete ca; delete cb; return 0;}
demo2:
#include#include #include #include #include struct Test{ int number{10};};void func(Test t);int main(){ int a = Test{}.number; //这里在c++11/14其实是不支持的,从c++17开始 pvalue -> xvalue.因此是正确的. std::cout << a << std::endl; std::cout << typeid(decltype(func(Test{}))).name() << std::endl; return 0;}