为什么在C ++ 11 / C ++ 14中针对自动和支撑初始化程序有特殊的类型推导规则?

菲利普·克拉森

Scott Meyers在他的CppCon 2014演讲者“类型推导和为什么要关心”中提出了一个问题,即为什么autoC ++ 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节中的额外自动扣除规则很有用?

TC

基本原理是在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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有统一初始化语法的自动类型推导c ++ 11 vs c ++ 17

来自分类Dev

为什么C ++ 11中需要decltype?

来自分类Dev

为什么在C ++ 11中需要decltype?

来自分类Dev

在C ++(98、11和14)中初始化静态数据成员的正确方法是什么?

来自分类Dev

为什么C ++ 11类内初始化程序不能使用括号?

来自分类Dev

为什么就地成员初始化在C ++ 11中使用副本构造函数?

来自分类Dev

为什么可变参数函数不能“吃掉” C ++ 11中的列表初始化参数?

来自分类Dev

为什么可变参数函数不能“吃掉” C ++ 11中的列表初始化参数?

来自分类Dev

为什么通过右值初始化非常量引用有效(在C ++ 11中)?

来自分类Dev

为什么通过右值初始化非常量引用有效(在C ++ 11中)?

来自分类Dev

为什么C ++ 11没有模板typedef?

来自分类Dev

为什么add函数在c ++ 11线程中无效?

来自分类Dev

为什么在c ++ 11中此Singleton不能正常工作?

来自分类Dev

为什么add函数在c ++ 11线程中无效?

来自分类Dev

自动进行C ++ 11初始化

来自分类Dev

自动进行C ++ 11初始化

来自分类Dev

为什么在C ++ 11或C ++ 14中没有安置迭代器?

来自分类Dev

在C ++ 11中使用支撑初始化初始化循环是否被认为是错误的形式?

来自分类Dev

为什么C ++ 11不允许使用auto进行直接列表初始化

来自分类Dev

为什么C ++ 11不允许使用auto进行直接列表初始化

来自分类Dev

C ++ 11和广义初始化程序约定

来自分类Dev

促进融合为什么在c ++ 11和c ++ 03中会有不同的结果?

来自分类Dev

C ++ 11中的默认初始化?

来自分类Dev

C ++ 11:列表初始化中的()或{}?

来自分类Dev

为什么C ++ 11中的统一初始化在虚拟基类上表现得怪异?

来自分类Dev

为什么以及额外的括号会如何更改C ++(C ++ 11)中的表达式类型?

来自分类Dev

C ++ 11中的数组声明和初始化

来自分类Dev

= {}和{}样式的初始化在C ++ 11中是否相同?

来自分类Dev

C ++ 11中的数组声明和初始化

Related 相关文章

  1. 1

    具有统一初始化语法的自动类型推导c ++ 11 vs c ++ 17

  2. 2

    为什么C ++ 11中需要decltype?

  3. 3

    为什么在C ++ 11中需要decltype?

  4. 4

    在C ++(98、11和14)中初始化静态数据成员的正确方法是什么?

  5. 5

    为什么C ++ 11类内初始化程序不能使用括号?

  6. 6

    为什么就地成员初始化在C ++ 11中使用副本构造函数?

  7. 7

    为什么可变参数函数不能“吃掉” C ++ 11中的列表初始化参数?

  8. 8

    为什么可变参数函数不能“吃掉” C ++ 11中的列表初始化参数?

  9. 9

    为什么通过右值初始化非常量引用有效(在C ++ 11中)?

  10. 10

    为什么通过右值初始化非常量引用有效(在C ++ 11中)?

  11. 11

    为什么C ++ 11没有模板typedef?

  12. 12

    为什么add函数在c ++ 11线程中无效?

  13. 13

    为什么在c ++ 11中此Singleton不能正常工作?

  14. 14

    为什么add函数在c ++ 11线程中无效?

  15. 15

    自动进行C ++ 11初始化

  16. 16

    自动进行C ++ 11初始化

  17. 17

    为什么在C ++ 11或C ++ 14中没有安置迭代器?

  18. 18

    在C ++ 11中使用支撑初始化初始化循环是否被认为是错误的形式?

  19. 19

    为什么C ++ 11不允许使用auto进行直接列表初始化

  20. 20

    为什么C ++ 11不允许使用auto进行直接列表初始化

  21. 21

    C ++ 11和广义初始化程序约定

  22. 22

    促进融合为什么在c ++ 11和c ++ 03中会有不同的结果?

  23. 23

    C ++ 11中的默认初始化?

  24. 24

    C ++ 11:列表初始化中的()或{}?

  25. 25

    为什么C ++ 11中的统一初始化在虚拟基类上表现得怪异?

  26. 26

    为什么以及额外的括号会如何更改C ++(C ++ 11)中的表达式类型?

  27. 27

    C ++ 11中的数组声明和初始化

  28. 28

    = {}和{}样式的初始化在C ++ 11中是否相同?

  29. 29

    C ++ 11中的数组声明和初始化

热门标签

归档