1,請緊緊記住一點auto的推斷實際上是跟template的推斷基本一致也有稍微的不一樣體如今std::initializer_list:node
2,不能推斷出一個模板中的另外一個模板的類型(template<template<typenaem T> class A>);
3, 當auto做爲函數的參數類型或者返回類型的時候auto類型的推斷規則無效!按照模板類型的推斷規則來.ios
case 1: autoc++
#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&express
#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; //p的類型是: int*(&); 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&spa
#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; //ptr的類型是:int* const(&),auto = int*; 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.net
#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; }
看了這麼可能是不是發現其實跟模板類型推斷同樣呢?那麼讓咱們來深刻吧:code
//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.
語法(C++14):
decltype(auto) variable initializer (since C++14) decltype(auto) function (since c++14)
針對: decltype(auto) function咱們能夠:
decltype(auto) function(int x, int y)
{
return (x+y); //其實至關於調用 auto function(int x, int y)->decltype(x+y)
}
If the declared type of the variable is decltype(auto), the keyword auto is replaced with the expression (or expression list) of its initializer, and the actual type is deduced using the rules for decltype.
針對: decltype(auto) variable initializer咱們能夠:
decltype(auto) i =10; //i的類型爲 int;
int x=10;
decltype(auto) y=(x); //至關於decltype((x)) y = x; 所以y的類型爲 int&.
decltype(auto) list={1, 2}; //error, 由於{1, 2}不是表達式.
auto list_={1, 2}; //ok!
參考: https://my.oschina.net/u/2516597/blog/538605