※ 引述《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
"使用者用爽爽,写编译器的人头超大"
拜托不要,里头每条特例都让人有杀人冲动