Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在C+;中有一个特殊的自动和带括号的初始值设定项类型推断规则+;11/C++;14?_C++_C++11_Auto_C++14_Initializer List - Fatal编程技术网

C++ 为什么在C+;中有一个特殊的自动和带括号的初始值设定项类型推断规则+;11/C++;14?

C++ 为什么在C+;中有一个特殊的自动和带括号的初始值设定项类型推断规则+;11/C++;14?,c++,c++11,auto,c++14,initializer-list,C++,C++11,Auto,C++14,Initializer List,Scott Meyers在其2014年CppCon演讲中提出了一个问题:为什么在C++11/C++14标准中有一条关于auto和带括号的初始值设定项的特殊规则(他的问题开始了) 自动与大括号初始列表组合的语义定义见§7.1.6.4/6 我想了想,也没能想出一个用例。到目前为止,我所看到的最接近的一件事是比亚恩·斯特罗斯特普使用它的一个例子 在his中,他曾使用auto捕获初始化者(但仅作为一种解决方法) 以下是代码(幻灯片30的一部分): 但请注意,这只是一种变通方法。他提到这不必要。相反,他

Scott Meyers在其2014年CppCon演讲中提出了一个问题:为什么在C++11/C++14标准中有一条关于
auto
和带括号的初始值设定项的特殊规则(他的问题开始了)

自动与大括号初始列表组合的语义定义见§7.1.6.4/6


我想了想,也没能想出一个用例。到目前为止,我所看到的最接近的一件事是比亚恩·斯特罗斯特普使用它的一个例子

在his中,他曾使用
auto
捕获初始化者(但仅作为一种解决方法)

以下是代码(幻灯片30的一部分):

但请注意,这只是一种变通方法。他提到这不必要。相反,他更愿意直接将参数传递给函数。因此,它不能真正成为
auto
和初始值设定项列表的良好动机


我对C++的理解不够深入,无法判断BjARNE的示例中允许初始化列表的缺点。无论如何,在这种情况下,它将避免使用

auto

那么,
auto
和初始值设定项列表是否仅仅是一个解决问题的方法?还是有好的例子,其中§7.1.6.4/6中的额外自动扣除规则是有用的?

基本原理是,一般来说,它想要禁止从括号内的初始值设定项列表中扣除普通类型参数:

从一开始就被认为是可取的行为 EWG关于初始值设定项列表的讨论。而不是想出一个 与{}列表匹配的参数类型
T
的智能推断规则 (我们在本文的早期草图和草稿中采用了这一选项), 我们现在更喜欢用“auto”变量的特例来处理这个问题 当初始值设定项是{}-列表时的推断。即,对于特定的 使用“自动”类型说明符和 {}-列表初始值设定项,将“auto”推断为函数
f(初始值设定项列表)
而不是函数的as
f(T)


Scott Meyers在一篇博客文章中谈到了这个话题:

就像T.C.的回答一样,它也提到了。已添加特殊扣除规则,以允许这样的代码工作:

 auto x = { 1, 1, 2, 3, 5 };
 f(x);
 g(x);
斯科特在博客中引用了詹姆斯·霍普金的以下解释:

简短的故事是,提出了一个特例,即auto应该将括号内的初始值设定项推断为初始值设定项列表,而没有意识到这样做破坏了统一的初始化(例如,它使
intx{7};
autox{7};
非常不同)。通过(当然!)引入另一种特殊情况修复了这一问题:带括号的单参数初始值设定项有自己的规则

更详细一点:尝试保持模板参数推导简单,但尝试通过将括号内的初始值设定项分配给自动函数,将其传递给两个或多个函数。这句话后来变成了书面语。请注意,Stroustrup以前在中的设计允许为无约束模板参数和auto推导初始值设定项列表,这更为一致,但也破坏了统一的初始化

所有这些都不能解释为什么我们不删除汽车的特殊情况。这不会导致对代码含义的无声更改,也不会简化语言


我很确定有一个C++1z建议,使
autoX={expr}使用
expr
类型(减号允许使用非括号逗号运算符)。不过,我不确定完整的列表还应该使用哪种类型。@christ我想你是指N3922。斯科特·梅耶斯也提到了这一点。VisualStudio已经实现了它,尽管它不是C++14的一部分。这是链接:啊,就是这个。虽然由于这个用法,我不得不有点不同意一般的说法。我真的希望格式不正确,并且初始化列表能够在没有额外行的情况下传递到函数中。
template<class T>
void inc(T, int); // (1)

template<class T>
void inc(std::initializer_list<T>, long); // (2)

inc({1, 2, 3}, 3); // Calls (2). (If deduction had succeeded
                   // for (1), (1) would have been called — a
                   // surprise.)
auto x = { 1, 1, 2, 3, 5 };
f(x);
g(x);
 auto x = { 1, 1, 2, 3, 5 };
 f(x);
 g(x);