C++17 几乎统一的初始化

德国迪亚哥

在本视频的结尾(从 15:57 开始),提供了有关如何在 C++17 中使用几乎统一初始化的建议:此处的视频

要点是这样的:始终使用直接初始化auto a{...};MyType a{...};不要= {...}对您的类型使用复制初始化

#include <iostream>


struct MyType {
    explicit MyType(std::initializer_list<int>) {
        std::cout << "Called std::initializer_list<int>" << std::endl;
    }

    explicit MyType(int) {
        std::cout << "Called int." << std::endl;
    }

    MyType(int, int, int) {
        std::cout << "Called int, int, int" << std::endl;
    }
};



int main() {
    MyType calls_init_list{10}; //Calls initializer_list<int>
    MyType calls_init_list_2{10, 20}; //Calls initializer_list<int>
    MyType calls_init_list_3{10, 20, 30}; //Calls initializer_list<int>

    MyType compile_error = {10, 20, 30}; //Compile error
}

如果我从第一个构造函数中删除显式,它也会调用第四个调用 initializer_list<int>

  1. 我需要进行哪些更改才能拨打电话(int)(int, int, int)遵守视频中的规则?
  2. 在初始化列表构造函数存在的情况下甚至可以调用其他构造函数吗?
  3. 有什么设计建议可以避免放弃视频中建议的一般规则?最终有一些有意义的东西会很好,C++ 初始化可能是其中最糟糕的部分。
尼可波拉斯

我需要进行哪些更改才能按照视频中的规则调用 (int) 和 (int, int, int)?

删除initializer_list<int>构造函数。这是让它发挥作用的唯一方法。

在初始化列表构造函数存在的情况下甚至可以调用其他构造函数吗?

是的,只要括号初始化列表中的类型不能匹配任何initializer_list<T>构造函数中的类型。他们始终处于领先地位。

这就是为什么它被嘲笑地称为“几乎一致的初始化”。

典型的解决方案是在非initializer_list构造函数中添加一些标签类型

struct tag_t {};
constexpr inline tag_t tag;

struct MyType {
    explicit MyType(std::initializer_list<int>) {
        std::cout << "Called std::initializer_list<int>" << std::endl;
    }

    MyType(tag_t, int) {
        std::cout << "Called int." << std::endl;
    }

    MyType(tag_t, int, int, int) {
        std::cout << "Called int, int, int" << std::endl;
    }
};

int main() {
    MyType three_int = {tag, 10, 20, 30}; //Calls 3-`int` constructor
}

有什么设计建议可以避免放弃视频中建议的一般规则?

好吧,考虑到“一般规则”不是一个好的规则(他的幻灯片包含典型的反例:尝试调用vector<int>with 大括号的 size+value 版本),最好放弃它。除了auto a{2};字面上无法调用某些构造函数之外,关于翻译成什么的小争论是无关紧要的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++ 17中不可复制变量的成员初始化

C ++标准是否保证统一初始化是异常安全的?

类C,构造函数和统一初始化之间有什么区别?

C ++ 11统一初始化:初始化列表和多参数构造函数之间的歧义?

Eclipse格式不正确的C ++ 11统一初始化

非聚集上的C ++ 14统一初始化

C ++ 11统一初始化:字段初始化器不是常量

C ++ 11统一初始化和函数重载

C ++-具有std :: string的统一初始化程序

c ++ 17聚合初始化

C ++ 17折叠表达式的限制类型,用于初始化模板类

我应该担心C ++ 17中的Wmissing-field-initializers和聚合初始化吗?

C17如何让我初始化原子?

在C ++ 17之前是否存在if语句的初始化?

C ++ 17中的向量初始化

C数组和结构中的C ++统一初始化

为什么这种直接初始化有效?(C ++ 17)

统一初始化导致C ++中的运行时错误

统一支撑数组初始化的保证复制省略-从C ++ 17开始这不是强制性的吗?

在C ++ 17中初始化后可以更改内联变量吗?

C ++ 17 if语句带有初始化但无条件

从C ++ 17开始的prvalue差异中的直接列表初始化与复制列表初始化与复制初始化的示例

在C ++ 17中初始化int向量的向量

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

C ++ 11在constexpr函数中使用统一值初始化数组

放宽 C++17 中的副本初始化要求

C++17 之前的聚合初始化

CRTP 基私有构造函数和派生的友元类使用 C++17 和统一初始化导致编译错误

在 C++11/17 中的类初始化和直接初始化中。有什么区别?