当一个结构有c-tor时,为什么我不能静态初始化它呢?

时间:2012-08-28 15:45:31

标签: c++ static constructor initialization structure

我的问题:当一个结构有c-tor时,为什么我不能静态初始化它?

我的编译器声称:

type `myStruct' must be initialized by constructor, not by `{...}'

为什么?我正在使用gcc版本3.4.4(cygming special,gdc 0.12,使用dmd 0.125)

为了说明,这里是编译器拒绝的struct

struct myStruct
{
    int a;
    double b;

    myStruct() { a= 0; b = 0.0; }
}

void main()
{
    myStruct ms = {7, 7.7}; // Now this compiler does not accept.
} 

4 个答案:

答案 0 :(得分:7)

包含用户定义的c-tor意味着它不再是聚合类型。如果struct本身没有用户定义的c-tor,但是struct的非静态数据成员不是POD或聚合类型,也会出现这种情况。

答案 1 :(得分:4)

因为语言以这种方式指定......

原因是构造函数是将对象初始化为有效状态的指定方式,因此直接将值转储到字段中是没有意义的。想法是要么有一个值集合,要么是一个自包含的对象但是你想做的事情会让它变成两者。

答案 2 :(得分:3)

只能使用初始化列表初始化聚合。根据8.5.1:1,包含用户提供的构造函数可防止结构或类成为聚合:

  

     

8.5.1聚合[dcl.init.aggr]

     

1 - 聚合是一个数组或类(第9条),没有用户提供的构造函数[...]

在C ++ 03中,

  

     

8.5.1 - 聚合[dcl.init.aggr]

     

1 - 聚合是一个数组或类(子类),没有用户声明的构造函数[...]

汇总与POD不同( 9:10);并非所有聚合都是POD,并非所有POD都是聚合;具有用户提供的析构函数的类可以是聚合但不是POD,而具有非复制非默认构造函数的类可以是POD但不是聚合。

演示:

#include <type_traits>
#include <iostream>

struct non_pod_aggregate { int i, j; ~non_pod_aggregate() {} };
struct non_aggregate_pod { int i, j; non_aggregate_pod(int) {}
    non_aggregate_pod() = default; };

int main() {
    std::cout << std::is_pod<non_pod_aggregate>::value << '\n'; // false
    std::cout << std::is_pod<non_aggregate_pod>::value << '\n'; // true
    non_pod_aggregate{0, 0};
    // non_aggregate_pod{0, 0}; // does not compile
}

在C ++ 03中,所有POD( 9:4)都是聚合,但仍然可能有不是POD的聚合;如上所述,用户提供的析构函数足以使结构取消POD资格。

答案 3 :(得分:1)

在C ++ 03中,列表初始化仅适用于聚合。您需要更改代码以调用构造函数:

myStruct ms;

如果您希望能够为所有成员指定值,则需要添加一个带有足够参数的构造函数:

struct myStruct
{
    int a;
    double b;

    myStruct() : a(), b() { }
    myStruct(int a, double b) : a(a), b(b) { }
};

void main()
{
    myStruct ms(7, 7.7);
}