問題描述
我知道,給定一個花括號初始化器,auto
將推導出 std::initializer_list
的類型,而模板類型推導將失敗:
auto var = { 1, 2, 3 };//類型推導為 std::initializer_list模板void f(T 參數);f({ 1, 2, 3 });//不編譯;類型推導失敗
我什至知道這是在 C++11 標準中指定的地方:14.8.2.5/5 bullet 5:
<塊引用>[如果程序有,它是一個非推導的上下文]一個函數參數,它的關聯參數是一個初始化列表(8.5.4)但是參數沒有 std::initializer_list 或對可能有 cv 限定的 std::initializer_list 的引用類型.[ 示例:
模板 void g(T);
g({1,2,3});//錯誤:沒有為 T 推導出參數
—結束示例 ]
我不知道或不明白的是為什么存在類型推導行為的這種差異.C++14 CD 中的規范與 C++11 中的規范相同,因此大概標準化委員會不會將 C++11 行為視為缺陷.
有誰知道為什么 auto
推導出一個花括號初始化器的類型,但不允許模板?雖然對這可能是原因"這種形式的推測性解釋很有趣,但我對那些知道標準為何如此編寫的人的解釋特別感興趣.
模板不做任何演繹的重要原因有兩個(我記得和負責人討論的兩個)
對未來語言擴展的擔憂(您可以發明多種含義 - 如果我們想為帶括號的初始化列表函數參數引入完美轉發呢?)
大括號有時可以有效地初始化一個依賴的函數參數
template無效分配(T&d,const T& s);
int main() {向量v;分配(v, { 1, 2, 3 });}
如果 T
將在右側推導出到 initializer_list
但在左側推導出 vector
,這會因為自相矛盾的論證推論而失敗.
auto
到 initializer_list
的推導是有爭議的.存在 C++-after-14 刪除它的提議(并禁止使用 { }
或 {a, b}
進行初始化,并使 {a}
推導出a
的類型).
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
).
這篇關于為什么花括號初始化器的自動和模板類型推導不同?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!