※ 引述《RealJack ()》之銘言:
: const int ci=1;
: auto &g=ci; //g的type為const int&
: const auto &h=2; //要自行加上const
首先,C++11有很多新功能其實是用舊的東西兜出來的
cv auto ref foo = expr;
(cv: const / volatile, ref: & / &&)
這個式子中auto最後所代表的型態等同於
template<class T>
void f(cv T ref t);
這個函式用 f(expr)呼叫時導出的U的型態
所以當
auto &g = ci;
時相當於回答 void f( T &t) 用 f(ci)呼叫時得到的T是什麼
樣板參數 呼叫參數
P = T& A= const int
根據標準把 T&換成 T
(取呼叫參數的reference而已,呼叫參數自己不必是reference)
解P == A
得到 T == const int
帶回去 [const int] &g = ci
天下太平
可是當改成用 f(2)呼叫的時候麻煩就大了
首先[ 2 ]的型態是什麼?
int。
很不幸的lvalue、rvalue什麼的是expression category,不是type的一部分
而template中只有P = T&&這種類型才會去檢查expression category。
所以一樣
P = T A = int
得到 T = int
帶回去 [int] &h = 2;
完蛋了標準禁止把 reference榜到rvalue expression上
總而言之
對template而言[ 2 ]的不是什麼 const int&&,而就是int而已
如果你寫 auto &i = "2";就OK,
因為"2"的型態是const char *
除非你用T&&要求template做檢查,不然他根本不鳥你什麼lvalue rvalue
有沒有可能讓他聰明一點?
如果你要自動搞定任何reference,那你應該用
auto &&foo = bar;
auto &說不定也可以變聰明讓他自動加const
但是標準中最令人頭大的就是template這章
引用STL講 template argument deduction時說的
http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/
Stephan-T-Lavavej-Core-C-2-of-n
"使用者用爽爽,寫編譯器的人頭超大"
拜託不要,裡頭每條特例都讓人有殺人衝動