c 11 auto,decltype型別推導

2021-09-08 22:20:45 字數 4247 閱讀 7801

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...