为什么大括号初始化器的自动类型推导和模板类型推导不同?

2024-01-01

我明白,给定一个支撑初始化器,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 项目符号 5:

[如果程序有,则为非推导上下文] 关联参数是初始值设定项列表 (8.5.4) 但参数的函数参数 没有 std::initializer_list 或对可能 cv 限定的 std::initializer_list 的引用 类型。 [Example:

模板无效 g(T);

g({1,2,3}); // 错误:没有为 T 推导出参数

结束示例 ]

我不知道或不明白的是why类型推导行为存在这种差异。 C++14 CD 中的规范与 C++11 中的规范相同,因此标准化委员会大概不会将 C++11 行为视为缺陷。

有谁知道为什么auto推导出花括号初始化器的类型,但模板不允许这样做?虽然“这可能是原因”这种形式的推测性解释很有趣,但我对那些人的解释特别感兴趣know为什么标准是这样编写的。


模板不做任何推导有两个重要原因(这两个是我和负责人讨论时记得的)

  • 对未来语言扩展的担忧(您可以发明多种含义 - 如果我们想为带括号的初始化列表函数参数引入完美转发怎么办?)

  • 大括号有时可以有效地初始化依赖的函数参数

template<typename T>
void assign(T &d, const T& s);
int main() {
  vector<int> v;
  assign(v, { 1, 2, 3 });
}

If T将在右侧推导为initializer_list<int>但在左侧vector<int>,由于自相矛盾的论证推导,这将失败。

扣除额为auto to initializer_list<T>是有争议的。存在 C++-after-14 删除它的提案(并禁止使用{ } or {a, b},并使得{a}推导出类型a).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么大括号初始化器的自动类型推导和模板类型推导不同? 的相关文章

随机推荐