17几乎统一的初始化

17几乎统一的初始化

本文介绍了C ++ 17几乎统一的初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

At the end of this video (starting at 15:57) there is advice on how to use almost uniform initialization in C++17: video here

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

The gist goes like this: use always direct initialization auto a{...}; and MyType a{...};Do not use copy initialization = {...} for your types.

#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>

If I remove explicit from the first constructor it will call the 4th call also with initializer_list<int>

  1. 要按照视频中的规则呼叫(int)(int, int, int),我需要进行哪些更改?
  2. 在初始化列表构造器存在的情况下甚至可以调用其他构造器吗?
  3. 有什么设计建议可以避免放弃视频中建议的一般规则?终于有了有意义的东西会很好,C ++初始化可能是其中最可怕的部分.
  1. What changes should I need for being able to call (int) and (int, int, int) following the rule in the video?
  2. Is it even possible to call the other constructors in the presence of the initializer list constructor?
  3. any design recommendations to avoid abandoning the general rule adviced in the video? It would be nice to finally have something that makes sense, C++ initialization is the most terrible part of it probably.

推荐答案

删除initializer_list<int>构造函数.这是使其工作的唯一方法.

Remove the initializer_list<int> constructor. That is the only way to make it work.

是的,只要braced-init-list 中的类型不能匹配,则必须与任何initializer_list<T>构造函数中的类型匹配.他们总是具有首要地位.

Yes, so long as the types in the braced-init-list cannot match those in the any initializer_list<T> constructors. They always have primacy.

这就是为什么它被戏称为" 几乎 统一初始化".

Hence why it's derisively called "almost uniform initialization".

典型的解决方案是向非initializer_list构造函数添加一些标记类型:

The typical solution is to add some tag type to the non-initializer_list constructors:

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>的大小+值版本),最好放弃它.关于auto a{2};所翻译内容的细微疑问与实际上无法调用某些构造函数无关.

Well, considering that the "general rule" is not a good rule (his slide contains the quintessential counter-example: try to call the size+value version of vector<int> with braces), it's better to abandon it. Minor quibbles about what auto a{2}; translates into are irrelevant next to being literally incapable of calling some constructors.

这篇关于C ++ 17几乎统一的初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:50