问题描述
在此视频的结尾(从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>
- 要按照视频中的规则呼叫
(int)
和(int, int, int)
,我需要进行哪些更改? - 在初始化列表构造器存在的情况下甚至可以调用其他构造器吗? 有什么设计建议可以避免放弃视频中建议的一般规则?终于有了有意义的东西会很好,C ++初始化可能是其中最可怕的部分.
- What changes should I need for being able to call
(int)
and(int, int, int)
following the rule in the video? - Is it even possible to call the other constructors in the presence of the initializer list constructor?
- 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几乎统一的初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!