Effective C++: auto类型推断.

1,请牢牢记住一点auto的推断其实是跟template的推断一致的:

2,不能推断出一个模板中的另一个模板的类型,
 3, 当auto作为函数的参数类型或者返回类型的时候auto类型的推断规则无效!按照模板类型的推断规则来.

case 1: auto

 #include <iostream>
int main()
{
 int x = 27;
 int& xx = x;
 const int cx = x;
 const int& rx = x;
 
 auto n_ = 10; //auto = int;
 auto x_ = x; //auto = int;
 auto xx_ = x;//auto = int;
 xx_ = 100;
 std::cout<<x<<std::endl;
 auto cx_ = cx; //auto = int;
 auto rx_ = rx; //auto = int;
 
 cx_ = 10; //ok, but x is also 27.
 rx_ = 100;//as same sa above.
 
 
 return 0;
}

case 2:auto&

#include <iostream>
class Node{
 public:
  Node()=default;
  ~Node(){ std::cout<<"destroy"<<std::endl; }
};
int main()
{
 int x = 27;
 int& xx = x;
 const int cx = x;
 const int& rx = x;
 
 
 auto& x_ = x; //auto = int;
 x_ = 1;       //x = 1, now.
 std::cout<< x <<std::endl;
 
 auto& xx_ = x; //auto = int;
 xx_ = 2;
 std::cout<< xx_ <<std::endl;
 
 auto& cx_ = cx; //auto = const int;
 //cx_ = 3; //error.
 
 auto& rx_ = rx; //auto = const int;
 
 int* ptr = new int(2);
 //auto& p = &x; //error.
 auto& p =ptr; //auto = int* (&); p是一个对ptr的引用. 
 *p = 10;
 std::cout<<p<<"  "<<ptr<<std::endl; //地址一样. 
 std::cout<<*p<<"  "<<*ptr<<std::endl;//数据一致. 
 delete ptr;
 
 int* ptr_two = new int(3);
 int* ptr_three = new int(4);
 std::cout<<ptr_two<<"  "<<ptr_three<<std::endl;
 
 auto& p_two = ptr_two;
 p_two = ptr_three; //现在ptr_two和p_two都指向了ptr_three. new int(3)还留在堆内!!内存泄漏了. 
 std::cout<<ptr_two<<"  "<<p_two<<std::endl;
 std::cout<<*ptr_two<<"  "<<*p_two<<std::endl;
 
 
 Node* ptr_node = new Node;
 auto& p_node = ptr_node;
 
 delete ptr_node;
 
 return 0;
}

case3: const auto

#include <iostream>
int main()
{
 int x = 27;
 const int cx = x;
 const int& rx = x;
 
 const auto y = 27; 
 const auto x_ = 2; //auto = int;
 const auto xx_ = x; //auto = int;
 const auto cx_ = cx; //auto = int;
 const auto rx_ = rx; //auto = int;
 
 int* ptr = new int(10);
 int* ptr_two = new int(20);
 const auto p = ptr;        //auto = int* , p的类型为int* const. 
 std::cout<<p<<"  "<<ptr<<std::endl;
 std::cout<<*p<<"  "<<*ptr<<std::endl;
 
 *p = 30;
 std::cout<<*p<<"  "<<*ptr<<std::endl;
 
 p = ptr_two; //error, p是一个顶层const. 
 
 delete ptr;
 delete ptr_two; 
 
 return 0;
}

case4: auto&&

 #include <iostream>
int main()
{
 int x = 27;
 const int cx = x;
 const int& rx = x;
 
 auto&& xx = 27; //auto = int;
 auto&& x_ = x; //auto = int&; 引用折叠 && + & = &; 
 x_ = 1;
 std::cout<< x <<std::endl;
 
 auto&& cx_ = cx; //auto = const int&; 引用折叠 && + & = &; 
 
 auto&& rx_ = rx; //auto = const int&; 同上. 
 
 return 0;
}

case 5: const auto&

#include <iostream>
int main()
{
 int x =27;
 const int cx = x;
 const int& rx = x;
 
 const auto& xx = 1; //auto = int;
 const auto& x_ = x; //auto = int&;发生了引用折叠&+&=&.
 const auto& cx_ = cx; //auto = int&;同上.
 const auto& rx_ = rx; //auto = int&;同上.
 
 int* ptr = new int(10);
 int* ptr_two = new int(20);
 const auto& p = ptr; //auto = int* const(&),p是一个对int* const类型的指针的引用!!!是引用!!!指针也能被引用!!.
 std::cout<<ptr<<"  "<<p<<std::endl;
 std::cout<<*ptr<<"  "<<*p<<std::endl;
 
 *p = 30;
 std::cout<<*ptr<<"  "<<*p<<std::endl;
 
 //p = ptr_two; //error, 这是一个顶层const 
 
 delete ptr;
 delete ptr_two;
 return 0;
}

case 6:数组和auto

#include <iostream>
int number_array[]{1, 2, 3};
int* arr = new int[3]{4, 5, 6};
const int* const ptr = nullptr;
int main()
{
 auto first = number_array; //auto = int* ;
 auto first_ = arr; //auto = int*;
 std::cout<<std::boolalpha<<std::is_same<int*, decltype(first)>::value<<" ";//输出: true.
 std::cout<<std::is_same<int*, decltype(first_)>::value<<std::endl;        //true.
  
 auto& second = number_array; //auto = int[3]; second的类型是 int (&)[3]. 
 auto& second_ = arr;          //auto = int*; second_的类型是int*(&); 
 std::cout<<std::boolalpha<<std::is_same<int(&)[3], decltype(second)>::value<<" ";//true
 std::cout<<std::is_same<int* (&), decltype(second_)>::value<<std::endl;         //true
 
 auto&& third = number_array; //auto = int(&)[3]; third的类型是 int(&)[3]. 
 auto&& third_ = arr;         //auto = int*(&);   third_的类型是 int*(&);
 std::cout<<std::boolalpha<<std::is_same<int(&)[3], decltype(third)>::value<<" ";//true
 std::cout<<std::is_same<int* (&), decltype(third_)>::value<<std::endl;         //true
 
 const auto forth = number_array; //auto = int*; forth的类型为: int* const,一个顶层const的指针. 
 const auto forth_ = arr;         //auto = int*; forth_的类型为: int* const,顶层const. 
 std::cout<<std::boolalpha<<std::is_same<int* const, decltype(forth)>::value<<" "; //true 
 std::cout<<std::is_same<int* const, decltype(forth_)>::value<<std::endl;         //true
 
 const auto& fifth = number_array; //auto = int[3]; fifth的类型为 const int(&)[3];
 const auto& fifth_ = arr;         //auto = int*; fifth的类型为 int* (&) const; 
 std::cout<<std::boolalpha<<std::is_same<const int(&)[3], decltype(fifth)>::value<<" ";//true
 std::cout<<std::is_same<int* const(&), decltype(fifth_)>::value<<std::endl;          //true
 
 
 
 return 0;
}

case 7: 函数和auto

 #include <iostream>
void function(const int& a, const int& b)
{
 std::cout<<a<<"  "<<b<<std::endl;
}
int main()
{
 auto func = function; //void (*)(const int&, const int&);
 (*func)(2, 0); 
 
 auto& func1 = function; //void (const int&, const int&);
 func1(3, 4);
 
 return 0;
}

看了这么多是不是发现其实跟模板类型推断一样呢?那么让我们来深入吧:

//c++提供了我们多种赋值的方式.
int a = 1;
int a(1);
int a{3};
int a={2};

但是我们用auto的话呢?

auto a = 1; //auto = int;
auto b(1); //auto = int;
auto c{3}; //auto = std::initializer_list<int>;
auto d={4}; //auto = std::initializer_list<int>;

还有:

auto list{1, 2, 3.0}; 
//error,竟然错了因为auto的类型被推断为std::initializer_list<int>但是3.0是一个float.

template<typename T>
void function(T param)
{ ...}

f({1, 2, 3}); //error!!!!!!!!
//由此我们可以看出不能推断出一个模板中的另一个模板的类型.

auto createInitList() //error, 这里竟然是和模板类型的推断规则一致的.
{
  return {1, 2, 3};
 }
 
 
 
 std::vector<int> v;
 auto resetV= [&v](const auto& newV){ v = newV; }
 
 resetV({1, 2, 4}); //error,这里相当于是reset(const T& newV),用的也是模板类型的推断规则.

关于尾至返回类型:

 #include <iostream>
#include <vector>
template<typename Container, typename Index>
auto function(Container& container, const Index& index)->decltype(container[index])
//如果使用了尾置返回类型auto是不会做任何事情的,其类型推断还是主要来自于decltype.
//由于std::vector的T& operator[](index),返回的是一个引用所以decltype推断出的类型也是一个引用. 
{
 return container[index];
}
int main()
{
 std::vector<int> v{1};
 function(v, 0)=2;
 
 std::cout<<v[0]<<std::endl; //输出为2. 
 
 return 0;
}

 错误的使用:

auto x; //error,不能知道x的类型.

int x1 = 10;
auto& ptr = &x1; //error.

你可能感兴趣的:(Effective C++: auto类型推断.)