1

我有一个问题:使用以下 C++ 代码(使用 C 风格的结构),我收到以下错误:

elements of partially initialized array must have a default constructor

我假设它在谈论不知道如何隐式初始化 的其余元素test.a,但我不知道如何修复它。也许我需要简单地添加一个构造函数,但我不想更改结构定义(这只是我面临的实际问题的一个精简示例)。

typedef struct inner_t
{
    const char* a;
    const int b;
    const char* c[6];
} inner;

typedef struct outer_t
{
    const inner a[10];
} outer;

int main()
{
    outer test = {{
        { "hi!", 0, { "1", "2", "3", "4", "5", ""} },
        { "", -1, { "" } }
    }};

    return 0;
}

我不在乎我手动初始化的元素之后会发生什么。我只关心我没有得到错误。

感谢您的任何帮助!

编辑:如果我添加一个默认构造函数inner喜欢这样:

typedef struct inner_t
{
    /* previous stuff */
    inner_t() : a(""), b(-1) { }
}

然后我得到更多错误:

initialization with '{...}' is not allowed for object of type "const inner"

我尝试添加不同的构造函数,但无济于事。我不明白为什么 C 风格的结构不只是一个默认的构造函数。

4

4 回答 4

2

首先,在 C++11 中,此代码应按原样编译。(在 C 中,此代码也将无任何错误地编译。)如果您收到此错误,则必须使用 C++11 之前的 C++ 编译器。

现在,关于您的声明:知道您为什么声明inner::bconst. 为什么是inner::b声明const,而不是inner::ainner::c?有什么特别之处inner::b

可以问同样的问题outer::a。为什么您决定const直接应用到特定成员outer::a而不是将整个outer对象声明为const

如果这不是故意的,那么您可以停止将单个结构成员声明为const,而是将整个test对象声明为const

typedef struct inner_t
{
    const char* a;
    int b;                       // <- removed `const` here
    const char* c[6];
} inner;

typedef struct outer_t
{
    inner a[10];                 // <- removed `const` here
} outer;

int main()
{
    const outer test = {{        // <- added `const` here
        { "hi!", 0, { "1", "2", "3", "4", "5", ""} },
        { "", -1, { "" } }
    }};

    return 0;
}

这将在 C++11 之前的编译器中编译。

但是如果出于某种充分的理由这是故意的,这意味着您不想更改声明,并且您希望将所涉及的类型保留为 C 样式聚合(即没有用户声明的构造函数),那么您的选择仅限于为单独声明为的所有数据字段提供所有初始化程序const

PS 使原始代码非法并使我的版本合法的 C++11 之前的语言规范中的措辞可以被认为是模棱两可和/或有缺陷的。这可能是 GCC 即使在-std=c++98模式下也接受原始代码但 MSVC++ 拒绝它的原因。

于 2013-07-12T18:23:06.257 回答
2

如果你想使用聚合初始化(这就是你正在做的),你不能有任何用户定义的构造函数。它必须看起来像普通的 C。请参阅initializer_list not working in VC10

如果你去掉const前面的那个词const int b,那么它就可以编译了(我在VS2008中试过)。

我认为您尝试做的事情是不可能的,因为声明const int b为结构的成员是一个 C++ 概念,需要您在构造函数中初始化 b ,但如果您使用聚合初始化器,则不允许有任何构造函数。

于 2013-07-12T18:28:13.413 回答
0

首先,我想提一下,您可能需要做的就是为“inner”添加一个默认构造函数。您已经提到您不想更改结构定义,但我认为您必须这样做。但是,我列出了一个替代方案。

你的问题:

'outer' 类型包含一个固定大小为 10 的数组,因此当变量“test”被初始化时,它会尝试使用给定的数据创建 10 个 'inner'。鉴于您提供的不够多,它无论如何都会尝试创建它们,但是您没有“内部”类型的默认构造函数,因此它不知道该怎么做。

解决方案:

1)(最简单)为'inner'创建一个默认构造函数。

2)使用指针或像std :: vector(c ++)/其他一些c类这样的类,使'outer'中的“a”数组成为动态数组。

希望有帮助。

于 2013-07-09T21:16:48.523 回答
0

您不需要将 const 变量更改为非常量,因为 const 变量可以初始化一次。原始代码在我的编译器(gcc 4.6.3)中使用 g++ 成功编译。并且在Visual C++中编译成功,但是将文件扩展名更改为*.c。

于 2013-07-14T06:55:20.897 回答