这是C++0x中一个未知大小的数组的列表初始化语法有效吗?

3
这个问题是关于C++0x中是否允许对未知大小的数组进行列表初始化。
int main() { int x[]{0, 1,2,3,4}; return x[0]; }

我认为这是有效的,但希望得到确认。

如果有人能够引用C++0x-FCD来支持他们的观点,那将不胜感激。

谢谢!

2个回答

4
这段内容涉及到IT技术,从8.5/16的第一个项目到8.5.4的列表初始化,再从8.5.4/3的第三个项目到8.5.1的聚合初始化,然后8.5.1/4表明:

用括号括起来的初始化列表初始化未知大小的数组,该列表包含n个初始化子句,其中应大于零,定义为具有元素

如果对象是数组,则= {...}{...}之间唯一的区别在于前者称为复制列表初始化,后者称为直接列表初始化,因此两者都是列表初始化的一种。在两种情况下,数组的元素都是从初始化列表的元素进行复制初始化。

请注意,如果数组有大小并且列表为空,则这些形式之间存在微妙的差异,在这种情况下,应用8.5.4的第二个项目:

struct A {
  explicit A();
};

A a[1]{};    // OK: explicit constructor can be used by direct initialization
A a[1] = {}; // ill-formed: copy initialization cannot use explicit constructor

如果列表中有内容,则不适用这种差异,此时第三个项目符号再次适用。

struct A {
  explicit A(int);
};

A a[1]{0};    // ill-formed: elements are copy initialized by 8.5.1
A a[1] = {0}; // ill-formed: same.

与先前的草案相比,FCD对此进行了更改,并且使用空的初始化列表进行初始化现在始终可以正常工作,即使使用显式默认构造函数也是如此。这是因为FCD声明的元素是值初始化的,而值初始化不关心显式性,因为它不会在默认构造函数上执行重载决议(无论如何都无法找到更好或更差的匹配项)。先前的草案在构造函数上使用正常的重载决议,因此在复制初始化期间拒绝显式默认构造函数。 这个缺陷报告做出了这个变化。


@Faisal,注意explicit A(int = 0);也是一个显式的默认构造函数。因此,这个改变可能会影响更多的程序,比人们最初想象的要多。但我认为FCD的行为更有益,因为“explicit”并没有真正涉及默认构造,而更多地涉及参数转换 :) - Johannes Schaub - litb
@Faisal,对于int(&&arr)[] = { 0 },我们有“否则,如果初始化列表只有一个元素,则从该元素初始化对象;”但是这听起来很奇怪,因为它似乎暗示这种情况只能发生在对象上,但实际上在这种情况下它发生在引用上。无论如何,如果我们将“对象”替换为“对象或引用”,那么它会尝试执行int(&&arr)[] = 0;,同样是不合法的。所以无论如何,你都不能这样做,但似乎标准对数组引用并没有好好考虑。 - Johannes Schaub - litb
我想我会尝试在这里发表评论(http://www.justsoftwaresolutions.co.uk/cplusplus/c++0x-now-at-fcd.html#makecomment),以便委员会可以尝试清理一下。虽然您可能更有资格发表评论。 - Faisal Vali
@Johannes - 再次感谢您严谨的洞察力。 对于阅读此评论的所有其他人,请为答案投票 - 答案及作者随后发表的评论所涉及的问题展现了对一个艰难话题的深刻见解。我希望我可以再投几次赞;) - Faisal Vali
@Faisal,谢谢你的赞美 :) 我认为我不是关于这个数组引用问题的好评论者,因为我怀疑委员会是否愿意支持它(他们在我的问题报告中发表评论称,他们通常希望避免数组临时变量)。 - Johannes Schaub - litb
显示剩余5条评论

0

是的,它是有效的,甚至在C语言中也是如此,大小只需设置为提供的元素数量即可。不幸的是,我不知道参考文献。

(额外加分...) 如果您需要元素的数量,请使用sizeof(x)/sizeof(*x)。这比硬编码可能因添加或删除条目而失效的常量更安全。

编辑:正如评论中指出的那样,所讨论的代码缺少一个=(我错过了这一点),没有它,在当前的C或C++标准中都是无效的。


5
错误。没有等号,它只在C++0x中有效(不在C++03中有效)。 - SoapBox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接