問(wèn)題描述
我知道,給定一個(gè)花括號(hào)初始化器,auto
將推導(dǎo)出 std::initializer_list
的類(lèi)型,而模板類(lèi)型推導(dǎo)將失敗:
auto var = { 1, 2, 3 };//類(lèi)型推導(dǎo)為 std::initializer_list模板void f(T 參數(shù));f({ 1, 2, 3 });//不編譯;類(lèi)型推導(dǎo)失敗
我什至知道這是在 C++11 標(biāo)準(zhǔn)中指定的地方:14.8.2.5/5 bullet 5:
<塊引用>[如果程序有,它是一個(gè)非推導(dǎo)的上下文]一個(gè)函數(shù)參數(shù),它的關(guān)聯(lián)參數(shù)是一個(gè)初始化列表(8.5.4)但是參數(shù)沒(méi)有 std::initializer_list 或?qū)赡苡?cv 限定的 std::initializer_list 的引用類(lèi)型.[ 示例:
模板 void g(T);
g({1,2,3});//錯(cuò)誤:沒(méi)有為 T 推導(dǎo)出參數(shù)
—結(jié)束示例 ]
我不知道或不明白的是為什么存在類(lèi)型推導(dǎo)行為的這種差異.C++14 CD 中的規(guī)范與 C++11 中的規(guī)范相同,因此大概標(biāo)準(zhǔn)化委員會(huì)不會(huì)將 C++11 行為視為缺陷.
有誰(shuí)知道為什么 auto
推導(dǎo)出一個(gè)花括號(hào)初始化器的類(lèi)型,但不允許模板?雖然對(duì)這可能是原因"這種形式的推測(cè)性解釋很有趣,但我對(duì)那些知道標(biāo)準(zhǔn)為何如此編寫(xiě)的人的解釋特別感興趣.
模板不做任何演繹的重要原因有兩個(gè)(我記得和負(fù)責(zé)人討論的兩個(gè))
對(duì)未來(lái)語(yǔ)言擴(kuò)展的擔(dān)憂(您可以發(fā)明多種含義 - 如果我們想為帶括號(hào)的初始化列表函數(shù)參數(shù)引入完美轉(zhuǎn)發(fā)呢?)
大括號(hào)有時(shí)可以有效地初始化一個(gè)依賴的函數(shù)參數(shù)
template無(wú)效分配(T&d,const T& s);
int main() {向量v;分配(v, { 1, 2, 3 });}
如果 T
將在右側(cè)推導(dǎo)出到 initializer_list
但在左側(cè)推導(dǎo)出 vector
,這會(huì)因?yàn)樽韵嗝艿恼撟C推論而失敗.
auto
到 initializer_list
的推導(dǎo)是有爭(zhēng)議的.存在 C++-after-14 刪除它的提議(并禁止使用 { }
或 {a, b}
進(jìn)行初始化,并使 {a}
推導(dǎo)出a
的類(lèi)型).
I understand that, given a braced initializer, auto
will deduce a type of std::initializer_list
, while template type deduction will fail:
auto var = { 1, 2, 3 }; // type deduced as std::initializer_list<int>
template<class T> void f(T parameter);
f({ 1, 2, 3 }); // doesn't compile; type deduction fails
I even know where this is specified in the C++11 standard: 14.8.2.5/5 bullet 5:
[It's a non-deduced context if the program has] A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type. [ Example:
template void g(T);
g({1,2,3}); // error: no argument deduced for T
—end example ]
What I don't know or understand is why this difference in type deduction behavior exists. The specification in the C++14 CD is the same as in C++11, so presumably the standardization committee doesn't view the C++11 behavior as a defect.
Does anybody know why auto
deduces a type for a braced initializer, but templates are not permitted to? While speculative explanations of the form "this could be the reason" are interesting, I'm especially interested in explanations from people who know why the standard was written the way it was.
There are two important reasons for templates not to do any deduction (the two that I remember in a discussion with the guy in charge)
Concerns about future language extensions (there are multiple meanings you could invent - what about if we wanted to introduce perfect forwarding for braced init list function arguments?)
The braces can sometimes validly initialize a function parameter that is dependent
template<typename T> void assign(T &d, const T& s);
int main() {
vector<int> v;
assign(v, { 1, 2, 3 });
}
If T
would be deduced at the right side to initializer_list<int>
but at the left side to vector<int>
, this would fail to work because of a contradictional argument deduction.
The deduction for auto
to initializer_list<T>
is controversial. There exist a proposal for C++-after-14 to remove it (and to ban initialization with { }
or {a, b}
, and to make {a}
deduce to the type of a
).
這篇關(guān)于為什么花括號(hào)初始化器的自動(dòng)和模板類(lèi)型推導(dǎo)不同?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!