我知道,给定一个大括号初始化器,auto
将推断出 std::initializer_list
的类型,而模板类型推断将失败:
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
我什至知道这在 C++11 标准中是在哪里指定的: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 ]
我不知道或不明白的是为什么存在这种类型推导行为的差异。 C++14 CD 中的规范与 C++11 中的规范相同,因此标准化委员会可能不会将 C++11 行为视为缺陷。
有人知道为什么 auto
会为大括号初始化器推导出类型,但不允许使用模板吗?虽然“这可能是原因”形式的推测性解释很有趣,但我对那些知道标准为何如此编写的人的解释特别感兴趣。
最佳答案
模板不做任何推论有两个重要原因(我记得在与负责人讨论中的两个)
对 future 语言扩展的担忧(您可以发明多种含义 - 如果我们想为大括号初始化列表函数参数引入完美转发呢?)
大括号有时可以有效地初始化依赖的函数参数
template<typename T> void assign(T &d, const T& s);
int main() {
vector<int> v;
assign(v, { 1, 2, 3 });
}
如果 T
将在右侧推导出为 initializer_list<int>
但在左侧 vector<int>
, 这会因为矛盾的论点推论而失败。
auto
的扣除至initializer_list<T>
是有争议的。有一个建议 C++-after-14 将其删除(并禁止使用 { }
或 {a, b}
进行初始化,并使 {a}
推断为 a
的类型)。
关于c++ - 为什么大括号初始值设定项的自动和模板类型推导不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17582667/