我不明白C++ 11大括号初始化规则在这里如何工作。
具有以下代码:

struct Position_pod {
    int x,y,z;
};

class Position {
public:
    Position(int x=0, int y=0, int z=0):x(x),y(y),z(z){}
    int x,y,z;
};

struct text_descriptor {
    int             id;
    Position_pod    pos;
    const int       &constNum;
};

struct text_descriptor td[3] = {
     {0, {465,223}, 123},
     {1, {465,262}, 123},
};

int main()
{
    return 0;
}

注意,该数组被声明为具有3个元素,但仅提供了2个初始化器。

但是,它编译时没有错误,这听起来很奇怪,因为最后一个数组元素的引用成员将未初始化。实际上,它具有NULL值:
(gdb) p td[2].constNum
$2 = (const int &) @0x0: <error reading variable>

现在是“魔术”:我将Position_pod更改为Position
struct text_descriptor {
    int             id;
    Position_pod    pos;
    const int       &constNum;
};

变成这个:
struct text_descriptor {
    int             id;
    Position        pos;
    const int       &constNum;
};

现在它给出了预期的错误:
error: uninitialized const member ‘text_descriptor::constNum'

我的问题:为什么在第一种情况下它应该给出错误时才进行编译(与第二种情况一样)。
不同之处在于Position_pod使用C-样式花括号初始化,而Position使用C++ 11-样式初始化,它们调用Position的构造函数。但是,这如何影响未引用成员初始化的可能性?

(更新)
编译器:
gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2

最佳答案

显然,



是列表初始化,并且初始化列表不为空。

C++ 11说([dcl.init.list] p3):



[dcl.init.aggr] p1:


td是一个数组,因此它是一个聚合,因此将执行聚合初始化。

[dcl.init.aggr] p7:



在这种情况下,因此td[2]是从一个空的初始化程序列表中初始化的,(再次[dcl.init.list] p3)表示它是值初始化的。

值初始化又意味着([dcl.init] p7):



您的类text_descriptor是一个没有用户提供的构造函数的类,因此td[2]首先被零初始化,然后调用其构造函数。

零初始化的方式([dcl.init] p5):



无论text_descriptor的默认构造函数如何,这都是定义明确的:它只是将非引用成员和子成员初始化为零。

如果非平凡的构造函数被调用,则默认构造函数被调用。这是定义默认构造函数([special] p5)的方法:



因此,按预期方式删除了隐式定义的构造函数,但是如果pos是POD类型(!),它也很简单。因为构造函数很简单,所以不调用它。因为没有调用构造函数,所以删除它的事实不是问题。

这是C++ 11中的一个漏洞,此漏洞已得到修复。碰巧已经修复了inaccessible trivial default constructors,但是措辞也涵盖了删除的琐碎默认构造函数。 N4140(大致为C++ 14)在[dcl.init.aggr] p7(强调我的)中说:



作为T.C.注释中指出,another DR也进行了更改,因此td[2]仍然是从空的初始化程序列表中初始化的,但是该空的初始化程序列表现在意味着聚合初始化。这又意味着每个td[2]的成员也都从一个空的初始化列表中初始化(再次[dcl.init.aggr] p7),因此似乎从{}初始化了引用成员。

然后[dcl.init.aggr] p9说(如remyabel在现已删除的答案中指出的那样):



我不清楚这是否适用于从隐式{}初始化的引用,但是编译器确实将其解释为相同的含义,并且含义不多。

关于c++ - C++ 11奇怪的括号初始化行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28408911/

10-11 22:54
查看更多