C++ 添加初始值设定项\u列表构造函数后,构造函数调用的静默中断 我们考虑如下: #include <iostream> #include <initializer_list> class Foo { public: Foo(int) { std::cout << "with int\n"; } }; int main() { Foo a{10}; // new style initialization Foo b(20); // old style initialization }
一切都好。现在,由于新的需求,我添加了一个构造函数,它采用初始值设定项列表C++ 添加初始值设定项\u列表构造函数后,构造函数调用的静默中断 我们考虑如下: #include <iostream> #include <initializer_list> class Foo { public: Foo(int) { std::cout << "with int\n"; } }; int main() { Foo a{10}; // new style initialization Foo b(20); // old style initialization },c++,c++11,initializer-list,C++,C++11,Initializer List,一切都好。现在,由于新的需求,我添加了一个构造函数,它采用初始值设定项列表 Foo(std::initializer_list<int>) { std::cout << "with initializer list\n"; } 因此,我的旧代码fooa{10}被悄悄地破坏了a应该用int初始化 据我所知,语言语法将{10}视为一个包含一项的列表。但我怎样才能防止这种对旧代码的无声破坏呢 是否有任何编译器选项会在此类情况下向我们发出警告?因为这将是特定于编译器的,
Foo(std::initializer_list<int>) {
std::cout << "with initializer list\n";
}
因此,我的旧代码fooa{10}
被悄悄地破坏了a
应该用int
初始化
据我所知,语言语法将{10}
视为一个包含一项的列表。但我怎样才能防止这种对旧代码的无声破坏呢
-Wall-Wextra
()
foob(20)
,并且仅当我们真正想要初始值设定项列表时才使用{}
我找不到这样的选项,所以显然在这种情况下,您应该对具有初始值设定项\u list构造函数的类使用括号,并根据需要对所有其他类进行统一初始化
在这个答案和注释中可以找到一些有用的见解:没有编译器警告,也永远不会有。警告代码做一些常见的事情是没有意义的,比如
std::vector vec{1};
请记住,编译器只警告真正不需要的东西,如未定义的行为。它无法知道在上面的定义中,您的意思是使用size参数调用构造函数。据它所知,你实际上想要一个有一个元素的向量!它无法读懂你的心思:)
第二个问题的答案基本上是肯定的。您始终可以添加一个伪参数,如struct{}dummy
避免将构造函数与初始值设定项列表一起使用,但实际上,唯一相同的解决方案是使用括号而不是大括号(或者不要突然中断接口)
如果要更改使用列表初始化的代码的每一部分,可以删除初始值设定项列表构造函数,将其更改为大括号,然后正确实现该构造函数。我会考虑这样的改变,一个适当的处理。另一个想法是提前提出初始化列表用例,并立即实施。在这些情况下不可能生成任何警告,因为在直接匹配上选择
std::initializer\u list
构造函数的行为定义良好,符合标准。
有关此问题的详细说明,请参见
第7项:
但是,如果一个或多个构造函数声明类型为的参数
std::initializer\u list
,使用括号内的初始化语法调用
强烈喜欢使用std::initializer\u列表的重载。强烈地。
如果编译器有任何方法可以使用大括号分析调用
初始值设定项是一个采用std::initializer\u列表的构造函数
,
编撰者将采用这种解释
他还介绍了这个问题的一些边缘案例,我强烈建议您阅读。为什么投票被否决?它措辞得体,可能对未来的读者有用。严肃地说,人们,否决投票是为了反映帖子质量,而不是你有多喜欢或不喜欢这个话题。答案是(2),在你展示的例子中,没有理由用大括号代替括号。正如
vector
所展示的,向现有接口添加一个初始值设定项\u list
构造函数是不可取的,除非其好处显著。旧代码没有这个问题,列表初始化是C++11的一个特性,这也是为什么标准库从来没有problems@PasserBy-正如他们所说,事后诸葛亮是20/20。说“史崔的结束”真是太傲慢了。代码库随着需求的变化和发展而变化。你不可能永远证明自己的未来。如果这听起来像是自高自大,我很抱歉,这正是我此刻在想的。我应该选择更仔细的词,就像你链接的答案描述了我所问的确切情况一样。而且似乎没有太多其他的选择来阻止它。
with initializer list
with int
std::vector vec{1};