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;
}
相關文章
相關標籤/搜索