Effective C++: std::decay和decltype

 std::decay:ios

// decay example
#include <iostream>
#include <type_traits>
typedef std::decay<int>::type A;           // int
typedef std::decay<int&>::type B;          // int
typedef std::decay<int&&>::type C;         // int
typedef std::decay<const int&>::type D;    // int
typedef std::decay<int[2]>::type E;        // int*
typedef std::decay<int(const int&)>::type F;  // int(*)(int)
typedef std::decay<int(&)[2]>::type G;     //int*

int main() {
  std::cout << std::boolalpha;
  std::cout << "typedefs of int:" << std::endl;
  std::cout << "A: " << std::is_same<int, A>::value << std::endl;  //输出均为:true. 
  std::cout << "B: " << std::is_same<int, B>::value << std::endl;
  std::cout << "C: " << std::is_same<int, C>::value << std::endl;
  std::cout << "D: " << std::is_same<int, D>::value << std::endl;
  std::cout << "E: " << std::is_same<int*, E>::value << std::endl;
  std::cout << "F: " << std::is_same<int (*)(const int&),F>::value << std::endl;
  std::cout << "G: " << std::is_same<int*, G>::value << std::endl;
  
  return 0;
}

 

decltype:c++

1,它并不会真正运行传入的表达式(unevalueted expression)。express

2, 若是传入的 表达式(expression)/变量名 是没有用圆括号扩住的(unparenthesized id-expression),那么咱们获取到的是只是该变量初次被声明的类型(这一点体如今class member data access 由于咱们可能 const className& value).ide

3, 若是咱们传入的 表达式(expression)/变量名 是用圆括号扩住的(parenthesized id-expression), 那么咱们获取到的就是它的实际(返回的)类型.函数

4, 针对unparenthesized expression状况:测试

     1) 若是传入的expression返回的是一个 xvalue,那么decltype获取到的类型为 T&&.this

    2) 若是传入的expression返回的是一个 lvalue,那么decltype获取到的类型为 T&.spa

   3) 若是传入的expression返回的是一个 xvalue,那么decltype获取到的类型为 T.c++11

5, 若是传入decltype的表达式是一个函数调用(function call), 且该函数接受参数,该函数所接受的参数必须是complete type, 可是该函数能够使incomplete type.code

6, C++17 structed-binding和decltype(待续).

 

 

语法:

decltype ( entity ) 	(1) 	(since C++11)
decltype ( expression )

 

demo1:

#include <iostream>
#include <type_traits>

//均是在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<int*, decltype(ptr)>::value << " \n"
			<< std::is_same<const int, decltype(number)>::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<int, decltype(n1)>::value << " \n" //输出都为:true.
		<< std::boolalpha << std::is_same<int&&, decltype(n2)>::value << " \n"
		<< std::boolalpha << std::is_same<const int, decltype(n3)>::value << " \n"
		<< std::boolalpha << std::is_same<const int&, decltype(n4)>::value << " \n"

		//注意下面的这些变量有些虽然是不能够修改的,可是仍然不显示const.
		<< std::boolalpha << std::is_same<int, decltype(a->number)>::value << " \n"
		<< std::boolalpha << std::is_same<int, decltype(a_.number)>::value << " \n"
		<< std::boolalpha << std::is_same<int, decltype(_a.number)>::value << " \n"
		<< std::boolalpha << std::is_same<int*, decltype(b->ptr)>::value << " \n"
		<< std::boolalpha << std::is_same<int*, decltype(b_.ptr)>::value << " \n"
		<< std::boolalpha << std::is_same<int*, decltype(_b.ptr)>::value << " \n"
		<< std::boolalpha << std::is_same<int*, decltype(cb->ptr)>::value << " \n";

	std::cout << std::endl;
	std::cout << std::is_same<int&, decltype((a->number))>::value << "\n"
		<< std::is_same<const int&, decltype((a_.number))>::value << "\n"
		<< std::is_same<const int&, decltype((_a.number))>::value << '\n'
		<< std::is_same<int*&, decltype((b->ptr))>::value << '\n'
		<< std::is_same<int* const &, decltype((b_.ptr))>::value << '\n'
		<< std::is_same<int* const &, decltype((_b.ptr))>::value << '\n'
		<< std::is_same<int* const &, decltype((cb->ptr))>::value << '\n';
		       
		    


	//c.print();


	delete a;
	delete b;
	delete ca;
	delete cb;
	return 0;
}

 

 

demo2:

#include <iostream>
#include <utility>
#include <tuple>
#include <array>
#include <typeinfo>




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;
}
相关文章
相关标签/搜索