Scott Meyers在他的CppCon 2014演讲者“类型推导和为什么要关心”中提出了一个问题,即为什么auto
C ++ 11 / C ++ 14标准中关于初始化和初始化初始化有特殊规则(他的问题开始于36m05s)。
§7.1.6.4/ 6中定义了auto与braced-init-list结合使用的语义。
我考虑了一下,也无法提出用例。到目前为止,我所看到的最接近的例子是Bjarne Stroustrup使用它的一个示例。
在他的Cpp 2014演讲中,“使简单任务变得简单!” ,他曾经使用auto
过捕获初始值设定项(但仅作为一种解决方法)。
这是代码(幻灯片30的一部分,位于37m10s):
// auto ss1 = collect({ 1, 2, 3, 4, 5, 6 }, odd); // error: Bummer!
auto lst = { 1, 2, 3, 4, 5, 6 };
auto ss2 = collect(lst, odd); // {1,3,5}
但是请注意,这只是一种解决方法。他提到没有必要。相反,他希望直接将参数传递给函数。因此,它不能真正充当auto
初始化列表的良好动机。
正如他建议的那样,我对C ++的理解还不足以判断允许在Bjarne的示例中使用初始化列表的弊端。无论如何,它将避免auto
在这种情况下的需要。
那么,auto
初始化器是否仅列出了可以更好解决的方法?还是有一些很好的示例,其中第7.1.6.4/6节中的额外自动扣除规则很有用?
基本原理是在N2640中,它通常想禁止从带括号的初始化程序列表中推导纯类型参数:
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
以下情况划出了一个特殊的例外:
在另一方面,能够推导出一个
initializer_list<X>
对T
是有吸引力的,允许:auto x = { 1, 1, 2, 3, 5 }; f(x); g(x);
自从EWG关于初始化程序列表的讨论开始以来,这种行为就被认为是理想的行为。现在,我们没有为
T
与{} -list匹配的参数类型提出一个巧妙的推导规则(我们在本文的早期草图和草稿中采用的选项),我们现在更喜欢使用“ auto”变量的特殊情况来处理此问题。当初始化程序为{} -list时推导。即,对于使用“自动”类型说明符和{} -list初始化程序声明的变量的特定情况,“自动”推导为函数f(initializer_list<T>)
而不是函数f(T)
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句