程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 《Effective Modern C++》Item 3總結,effectivemodernc

《Effective Modern C++》Item 3總結,effectivemodernc

編輯:C++入門知識

《Effective Modern C++》Item 3總結,effectivemodernc


decltype 總結

第一個值得說明的問題是,operator[] on a container of objects of type T typically returns a T&.[]操作符用於儲存T類型對象的容器時通常返回T&,具體問題需要具體分析,decltype一個[]操作符,返回類型依賴存儲它的容器。vector<bool>就比較特殊。

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

這段C++11代碼有效,但是存在一下問題,我們使用位置返回類型,並且使用c和i,對於其他函數如果無法獲取c和i,那麼無法使用decltype。這個方法可以完善。

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

這段C++14代碼不正確,從條款一,二可知,auto會把左值引用識別為去掉引用的部分,這裡其實我們需要返回左值引用。

template<typename Container, typename Index> // C++14; works,
decltype(auto) // but still
authAndAccess(Container& c, Index i) // requires
{ // refinement
authenticateUser();
return c[i];
}

decltype(auto)終於搞定了,我們不在需要尾置返回類型,並且類型識別為左值引用。但是這個方法仍然需要完善。

因為我們仍然需要面臨一個問題,這個模板無法使用右值。所以無法傳入一個臨時的容器對象。我們需要支持類似下面的操作

std::deque<std::string> makeStringDeque(); // factory function
// make copy of 5th element of deque returned
// from makeStringDeque
auto s = authAndAccess(makeStringDeque(), 5);

那麼需要引入新詞語,全球通引用和完美轉發,今年C++標准委員會開大會,決定把universal references正式更名為forwarding references(轉發引用),轉發引用一般用與完美轉發,需要深入了解一下std::forward和std::move兩個函數,以及右值引用和左值引用區別,這個後續條款有講,並且我也打算專門為右值引用寫一片文章。

template<typename Container, typename Index> // final
decltype(auto) // C++14
authAndAccess(Container&& c, Index i) // version
{
 authenticateUser();
 return std::forward<Container>(c)[i];
}

這樣一切都搞定了。

最後需要注意一些小問題,比如

int x;

decltype((x)) //type is int&

更詳細的細節:

1) If the argument is either the unparenthesised name of an object/function,sion (object.member or pointer-> or is a member access expresmember), then the decltype specifies the declared type of the entity specified by this expression. 2) If the argument is any other expression of type T, then a) if the value category of expression is xvalue, then the decltype specifies T&& b) if the value category of expression is lvalue, then the decltype specifies T& c) otherwise, decltype specifies T

除了括號非常特殊以外,decltype((變量,只有名字的表達式))的類型總會是個引用。如果是一個簡單的表達式(只有名字這種objec.member也算簡單),那麼decltype就是返回它的類型。

對於其他任何比較復雜的表達式,遵循2),

這裡給出一個英文的連接,供參考什麼是左值,右值,x值

http://en.cppreference.com/w/cpp/language/value_category

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved