是否有任何C++标准的计划来解决初始化列表构造函数的不一致性?

xda*_*liu 11 c++ constructor initializer-list c++-standard-library c++11

C++中的初始化列表构造函数经常会引起麻烦; 例如

using std::vector;
using std::string;
vector<string> v{3}; // vector of three empty strings
vector<int> u{3}; // vector of one element with value 3
Run Code Online (Sandbox Code Playgroud)

(只是为了澄清,我的意思是<int>构造函数是一个初始化列表构造函数,而<string>一个不是.)

int案例与初始化列表构造函数匹配,而string案例则不匹配.这有点难看,常常会造成麻烦.在Scott Meyers的Effective Modern C++的早期章节(第7项)中也注意到了这一点,他将其描述为标准中有些令人不快的部分,每当初始化列表构造函数可用时,编译器将跳过箍尝试匹配它,优先于每个其他构造函数.

当然,int case可以通过改变u{3}来轻松修复u(3),但这不是重点.

这是理想的行为吗?C++标准委员会是否有任何讨论或计划来解决这种模糊/不愉快?一个例子是要求初始化程序列表构造函数被调用,如下所示:vector<int> u({3})这已经是合法的.

Bar*_*rry 4

C++ 标准委员会是否有任何讨论或计划来解决这种类型的歧义/不愉快的情况?

自 C++11 以来,对初始化进行了许多修复。例如,您最初无法使用列表初始化 ( CWG 1467 ) 复制构造聚合。这个非常小的修复以一种不受欢迎的方式破坏了一些代码,从而导致一个新问题,需要改进之前的修复以在存在initializer_list构造函数时撤消它(CWG 2137)。即使在小情况下,也很难在不产生大量意外后果和破坏代码的情况下触及这些子句中的任何内容。我怀疑将来是否会推动对初始化进行任何重大更改。此时,代码损坏的数量将是巨大的。

最好的解决方案就是意识到初始化的陷阱并小心你正在做的事情。我的经验法则是仅{}当我故意需要提供的行为时才使用 s {}()否则使用 s 。

请注意,这与更广为人知的陷阱没有什么不同:

vector<int> a{10}; // vector of 1 element
vector<int> b(10); // vector of 10 elements
Run Code Online (Sandbox Code Playgroud)

一个例子是要求像这样调用初始化列表构造函数:vector<int> u({3}),这目前已经是合法的。

出于同样的原因,您遇到了与之前相同的问题:

vector<int> u({3});    // vector of one element: 3
vector<string> v({3}); // vector of three elements: "", "", and ""
Run Code Online (Sandbox Code Playgroud)

即使您需要前者(这是不可能的),您也不可能使后者格式错误。