为什么带括号的初始化程序的自动和模板类型推导会有所不同? [英] Why do auto and template type deduction differ for braced initializers?

查看:109
本文介绍了为什么带括号的初始化程序的自动和模板类型推导会有所不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,给定一个初始化初始化程序,auto会推断出std::initializer_list的类型,而模板类型的推导将失败:

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

我什至知道在C ++ 11标准中指定的位置:14.8.2.5/5项目符号5:

I even know where this is specified in the C++11 standard: 14.8.2.5/5 bullet 5:

[如果程序具有,则为非推论上下文]一个函数参数,与其关联的参数为初始化器列表(8.5.4),但参数为 没有std :: initializer_list或对可能具有cv资格的std :: initializer_list的引用 类型. [示例:

[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);

template void g(T);

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

g({1,2,3}); // error: no argument deduced for T

示例]

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

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.

有人知道为什么auto推断带括号的初始化程序的类型,但是不允许模板吗?尽管对这可能是原因"形式的投机性解释很有趣,但我对那些知道为何按原样编写标准的人的解释特别感兴趣.

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 });
}

如果将T推导到initializer_list<int>的右侧,但是将其推导到vector<int>的左侧,则由于自相矛盾的论证推导而无法工作.

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.

autoinitializer_list<T>的推论是有争议的.有一个提案建议将C ++-after-14删除它(并禁止使用{ }{a, b}进行初始化,并使{a}推导为a的类型).

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).

这篇关于为什么带括号的初始化程序的自动和模板类型推导会有所不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆