C++中结构的奇怪行为[第1部分]

Ins*_*der 53 c++

考虑:

struct box
{
    int array[3];
};

int main()
{
    box a = {1};
}
Run Code Online (Sandbox Code Playgroud)

如果以上工作在C++中那么为什么以下工作不起作用?

struct box
{
    int simple_int;
};

int main()
{
    box b = 2;
}
Run Code Online (Sandbox Code Playgroud)

是什么原因?

Eri*_*hil 87

正确地说,前者会使用box a = { { 1 } },因此每个聚合都有一组括号.外部括号组用于结构,内部组用于阵列.但是,该语言允许您省略内括号.

在后者中,没有内部括号可以省略.你不能省略外括号; 您必须至少有一组大括号来区分聚合的初始值设定项列表.从某种意义上说,大括号说"这是把团粒内部的事情列出来."当你写box b = 2,编译器不知道你想要把2 里面的总和.相反,看起来你正试图初始化b对象(而不是它的一部分)2.因此,编译器会尝试查找将a更改2为a 的构造函数或转换box.如果失败,则会出错.

  • @GrijeshChauhan:我省略了它,因为它不相关并使讨论复杂化.问题是为什么我们不能省略括号,而不是为什么我们可以添加它们.对于标量而言,语言规范是单独处理的,而不是聚合规则的一部分. (7认同)
  • 甚至我们也可以将int声明为:`int i = {10};` (5认同)
  • @InsaneCoder:粗略地说,聚合是由其他对象组成的对象.出于初始化目的,聚合是一个数组或类,没有用户声明的构造函数,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数.包含数组的普通结构是包含聚合的聚合. (3认同)
  • 谢谢Grijesh,我不知道! (2认同)
  • @AJMansfield:更确切地说,它意味着初始化结构的**第一个成员**,**必须是**数组或结构,到`{10,20,30}`,并将下一个成员初始化为` 50`.如果它不是第一个成员,它将不会找到要初始化的数组. (2认同)

Nei*_*irk 18

它不起作用,因为您的语法错误.您可以使用隐式构造函数添加对b = 2的支持,如果这是您想要的.

box b = {2}; // correct syntax with no constructor
Run Code Online (Sandbox Code Playgroud)

要么

struct box
{
    // implicit constructor
    box(int i) : i(i) {}
    int i;
};

box b(2);
box c = 2;
Run Code Online (Sandbox Code Playgroud)

要么

struct box
{
    explicit box(int i) : i(i) {}
    int i;
};

box b(2);
box c = 2; // disallowed
Run Code Online (Sandbox Code Playgroud)