auto型別推導
1. auto推導
auto x = 5; //被編譯器推導為int型別
auto pi = new auto(1); //編譯器推導為int
const auto* v = &x, u = 5; //v為 const int*, u為 const int
static auto y = 0.1; //y為static const double
auto s; //出錯! auto變數不能只宣告不初始化
2. auto推導規則
int x = 0;
auto *a = &x; //a為 int*
auto b = &x; //b為 int*,auto可以自動識別指標型別
auto &c = x; //c為 int&
const auto e = x; //e為const int
auto f = e; //f為int (非指標或引用,則不保留cv限定符)
const auto& g = x; //g 為 const int&
auto& h = g; //h 為 const int&(指標或引用,保留cv限定符)
auto k = g;
3. auto的限制
void func(auto a = 1){}; //錯誤。auto不能用於函式引數
struct foo
template
struct bar{};
int main();
auto aa = arr; //aa被推導為int*
auto rr[10] = arr; //錯誤,auto無法定義陣列
barbar;
barbb = bar; //錯誤,auto無法推導出模板引數
}
4. auto的使用場景
(1)變數型別名比較長比較複雜
//比如stl容器
std::map< double, double> result_map;
std::map< double, double>::iterator it = result_map.begin();
for(; it != result_map.end(); ++ it){};
//通過auto可以簡化為
for (auto it = result_map.begin(); it != result_map.end(); ++it);
std::unordered_multimap< int, int> result_map;
std::pair< std::unordered_multimap< int, int>::iterator, std::unordered_multimap< int, int>::iterator> range = result_map.equal_range(key);
//通過auto簡化為
auto range = result_map.equal_range(key);
(2)無法確定變數應該定義為什麼型別
class foo
};class bar
};templatevoid func(void)
int main()
decltype型別推導
1. decltype推導
int x = 0;
decltype(x) y = 3; //y被推導為int型別
decltype(x + y) z = 0; //z被推導為int
const int a = 1;
decltype(a) b = 2; //被推導為const int,儘管非指標或引用,仍然保持cv限定符
const int& i = 9;
decltype(i) h = x; //const int&
decltype(z)* p = &x; //p 為int*
decltype通過表示式得到的型別,可以保留住表示式的引用以及const限定符。對於一般的標記符表示式,decltype精確的推導出表示式定義本身的型別,不會像auto那樣捨棄引用和cv限定符。
2. decltype推導規則
(1) exp是識別符號,類訪問表示式,decltype(exp)和exp的型別一致
(2) exp是函式呼叫,decltype(exp)和返回值的型別一致
(3) 其他情況,若exp是乙個左值,則decltype(exp)是exp型別的左值引用,否則為和exp型別一致。
```(1)識別符號、類訪問表示式,則 decltype(exp)和exp的型別一致
class foo;
int n = 0;
volatile const int& x = n;
decltype(n) a = n; //int
decltype(x) b = n; //volatile const int&
decltype(foo::number) c = 0; //const int(沒有static)
foo foo;
decltype(foo.x) d = 0; //int型別
(2) 函式呼叫,decltype(f(xx)) 和 函式返回值型別一致
const foo f()
decltype(f()) c; //const foo
(3) 帶括號的表示式和加法運算表示式
struct foo;
const foo foo = foo();
decltype(foo.x) a = 0; //a 被推導為int, 根據推導規則1
decltype((foo.x))b = a; //b 被推導為const int&,
//因為根據foo.x 為乙個左值,可知括號表示式也是乙個左值。則按照推導規則3,返回左值的引用,foo為const foo,則foo.x為乙個const int型別的左值,則decltype的推導結果 為 const int&
int n = 1, m = 2;
decltype(n + m) c = 0; //c被推導為int, n + m 為右值,則推導規則3,
decltype(n += m) d = c; //d被推導為int &, n += m 為左值,則推導規則3,為exp的引用
//注意此時 n 仍然為1,而不是3,因為 decltype只是推導exp的型別,而不對exp進行求值
3. decltype的實際應用
(1)泛型程式設計中自動推導型別
decltype(containert().begin())it_;//獲得某種型別容器的迭代器
(2)通過變數表示式抽取變數型別
vectorv;
....
decltype(v)::value_type i = 0; //知道v是乙個vector,但是不知道裡面的資料型別,則可以使用 decltype(v)::value_type
返回型別後置語法,auto和decltype結合使用
int& foo(int& i);
float foo(float& f);
//有如上兩個函式,同名,但是返回值和引數型別不同。若想要用模板來實現兩個同名函式的呼叫。
templatedecltype(foo(val)) func(t&val) //這樣寫編譯不過,因為c++的返回值是前置語法,在返回值定義的時候引數變數還不存在,因此無法使用前置的decltype(foo(val)) 【需要獲得decltype(foo(val))的時候,val還不存在】
但可以通過auto和decltype的自動型別推導完成。
templateauto func(t& val) -> decltype(foo(val)) //返回值型別後置
C 中auto decltype與陣列
auto與decltype都是c 11中新引入的型別說明符。使用型別說明符auto,實際上就是讓編譯器來分析表示式所屬型別,所以auto定義的變數必須有初始值。auto i 1 此時編譯器會推斷變數i的型別是int。decltype的用法請參考 c 中decltype的使用方法 整型陣列a的定義如下...
c程式設計11
1.字元陣列輸入輸出函式 int gets charstr 衝鍵盤輸入乙個字串,儲存到str所指向的記憶體單元中 int puts charstr 輸出str所指向的位址中的字串並且換行 2.字串連線函式char strcat charstr1,char str2 將str2 所指向的字元,連線到s...
gcc g 如何支援c11 c 11標準編譯
cat aa.cc file main.cpp include int main for int i a return 0 g v gcc version 4.8.5 20150623 red hat 4.8.5 4 gcc g o aa g wall aa.cc aa.cc in function...