九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
c++11-17 模板核心知識(九)—— 理解decltype與decltype(auto)

與模板參數(shù)推導(dǎo)和auto推導(dǎo)一樣,decltype的結(jié)果大多數(shù)情況下是正常的,但是也有少部分情況是反直覺的。

decltype介紹

給定一個name或者expression,decltype會告訴你它的類型。

我們先從正常情況開始:

const int i = 0;            // decltype(i) is const intbool f(const Widget& w);    // decltype(w) is const Widget&                            // decltype(f) is bool(const Widget&)struct Point {  int x, y;         // decltype(Point::x) is int};          // decltype(Point::y) is intWidget w;        // decltype(w) is Widgetif (f(w)) …       // decltype(f(w)) is booltemplate<typename T>    // simplified version of std::vectorclass vector {public:…T& operator[](std::size_t index);…};vector<int> v;      // decltype(v) is vector<int>…if (v[0] == 0) …      // decltype(v[0]) is int&

很直觀,沒有例外情況。 注意:decltype與auto不同,不會消除const和引用。

為什么需要decltype

比如我們需要聲明一個函數(shù)模板,函數(shù)的返回值類型依賴函數(shù)參數(shù)的類型。在C++11中,常見的例子是返回一個container對應(yīng)索引的值:

template <typename Container, typename Index> // works, but requires refinementauto authAndAccess(Container &c, Index i) -> decltype(c[i]) {  return c[i];}

注意:這里的auto跟類型推導(dǎo)沒有任何關(guān)系,它只是表明了這里使用了C++11的trailing return type.

decltype(auto)

在C++11中只允許單語句的lambda表達式被推導(dǎo),在C++14中之中行為被拓展到所有l(wèi)ambda和所有函數(shù),包括多語句。在C++14中,上述代碼我們可以簡寫為:

template<typename Container, typename Index>        // C++14;  not quite correctauto authAndAccess(Container& c, Index i) {   return c[i];         // return type deduced from c[i]}

注意:這里的auto就跟類型推導(dǎo)有關(guān)系了。 在前面講auto推導(dǎo)規(guī)則的文章中提到過,auto作用在函數(shù)返回值時,使用的是模板參數(shù)推導(dǎo)規(guī)則,這里就會出現(xiàn)問題:operator []我們希望它返回引用,但是使用auto使用模板參數(shù)推導(dǎo)規(guī)則時,引用會被忽略,所以下面的代碼會報錯:

template <typename Container, typename Index>auto authAndAccess(Container &c, Index i) {  return c[i];}std::vector<int> v{1,2,3,4,5};authAndAccess(v,2) = 10;      // error: expression is not assignable

但是使用auto -> decltype()則不會報錯,因為這里auto不代表參數(shù)參數(shù)推導(dǎo):

template <typename Container, typename Index>auto authAndAccess(Container &c, Index i) -> decltype(c[i]) {  return c[i];}std::vector<int> v{1,2,3,4,5};authAndAccess(v,2) = 10;

所以,要想讓authAndAccess在使用auto的情況下返回引用,在C++14中,我們可以使用decltype(auto):

template <typename Container, typename Index>decltype(auto) authAndAccess(Container &c, Index i) {  return c[i];}std::vector<int> v{1,2,3,4,5};authAndAccess(v,2) = 10;

decltype(auto)中的auto代表返回值需要被自動推導(dǎo),decltype代表使用decltype來推導(dǎo)返回值類型。

decltype(auto)不僅可以聲明函數(shù)返回值,還可以聲明變量:

Widget w;const Widget& cw = w;       // auto type deduction : myWidget1's type is Widgetdecltype(auto) myWidget2 = cw;       // decltype type deduction : myWidget2's type is const Widget&

注意(entity)

decltype的規(guī)則可以看官網(wǎng):decltype specifier,概況下可以分為兩大類:

  • decltype ( entity ) : 如果entity是一個不被括號包圍的標(biāo)識符、類訪問表達式,那么decltype ( entity )與entity類型一致。

  • decltype ( expression ) : 如果expression是一個表達式,計算結(jié)果為類型T,那么:

    • 如果expression為xvalue,那么decltype的結(jié)果是T&&.

    • 如果expression為lvalue,那么decltype的結(jié)果是T&.

    • 如果expression為prvalue,那么decltype的結(jié)果是T.

注意第一點中強調(diào)了entity是一個不被括號包圍的標(biāo)識符。因為當(dāng)一個標(biāo)識符被括號包圍時,它就是一個左值表達式了,對應(yīng)上面第二大點的第二小點。比如說int x = 0;,x是一個標(biāo)識符,所以decltype(x)的結(jié)果為int。但是(x)就是一個左值表達式,decltype((x))的結(jié)果就是int&。所以下面的用法是不同的:

decltype(auto) f1() {int x = 0;    …    return x;       // decltype(x) is int, so f1 returns int}decltype(auto) f2() {    int x = 0;    …    return (x);     // decltype((x)) is int&, so f2 returns int&}

官網(wǎng)的例子能很好的概況decltype最常見的用法:

#include <iostream> struct A { double x; };const A* a; decltype(a->x) y;       // type of y is double (declared type)decltype((a->x)) z = y; // type of z is const double& (lvalue expression) template<typename T, typename U>auto add(T t, U u) -> decltype(t + u) // return type depends on template parameters                                      // return type can be deduced since C++14{    return t + u;} int main() {    int i = 33;    decltype(i) j = i * 2;     std::cout << "i = " << i << ", "              << "j = " << j << '\n';     auto f = [](int a, int b) -> int    {        return a * b;    };     decltype(f) g = f; // the type of a lambda function is unique and unnamed    i = f(2, 2);    j = g(3, 3);     std::cout << "i = " << i << ", "              << "j = " << j << '\n';}

(完)

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
30分鐘了解C++11新特性
c 11特性學(xué)習(xí)總結(jié)
C++ auto 關(guān)鍵字的使用
C++11常用新特性快速一覽
C++定義類的關(guān)鍵字——decltype
C++:C++11新特性詳解(1)
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服