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::bとして宣言した理由を知ることは興味深いでしょうconst。が宣言されているのにorがinner::b宣言されconstていないのはなぜですか? 何がそんなに特別なのですか?inner::ainner::cinner::b

について同じ質問をすることができますouter::a。オブジェクト全体を として宣言するのではなくconst、特定のメンバーに直接適用することにしたのはなぜですか?outer::aouterconst

それが意図的でない場合は、個々の構造体メンバーを as として宣言するのをやめて、代わりにオブジェクトconst全体をas として宣言することができます:testconst

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 以前の言語仕様の文言は、あいまいであるか、欠陥があると見なすことができます。これがおそらく、-std=c++98モードでも GCC が元のコードを受け入れるのに、MSVC++ がそれを拒否する理由です。

于 2013-07-12T18:23:06.257 に答える
0

First, I'd like to mention that all you probably need to do is add a default constructor for 'inner'. You've mentioned that you don't want to change the struct definitions, but I think that you'd have to. I have, however, listed an alternative.

Your problem:

The 'outer' type contains an array of fixed size 10, so when the variable "test" is initialised, it attempts to create 10 'inner's with the data given to it. Seeing as you aren't giving it enough, it attempts to create them anyway, but you don't have a default constructor for your 'inner' type so it doesn't know what to do.

Solutions:

1) (Simplest) Create a default constructor for 'inner'.

2) Make the "a" array in 'outer' a dynamic one, either using pointers or a class like std::vector (c++) / some other c class.

Hope that helps.

于 2013-07-09T21:16:48.523 に答える
0

const 変数を非 const に変更する必要はありません。const 変数は一度初期化できるためです。元のコードは、私のコンパイラ (gcc 4.6.3) で g++ を使用して正常にコンパイルされます。また、Visual C++ で正常にコンパイルされますが、ファイル拡張子を *.c に変更します。

于 2013-07-14T06:55:20.897 に答える