c++ - 为什么大括号初始值设定项的自动和模板类型推导不同?

标签 c++ c++11 templates template-argument-deduction list-initialization

我知道,给定一个大括号初始化器,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/

相关文章:

c++ - 用方法替换包装智能指针

c++ - 复制构造函数返回的值

c++ - 如何在 NACHOS (C++) 中创建类

c++ - 从按值构造函数参数初始化的引用成员

c++ - Lambda 和通过引用局部变量 : Accessing after the scope 捕获

c++ - 传递 std::plus<>() 作为谓词

c++ - std::bind 于 std::array 的运算符[]

javascript - 在 RenderingTemplate 中注册/包含 javascript

c++ - 模板参数推断失败

c++ - 如何消除并行 std::transform_reduce() 的中间容器?