2017-08-09 15 views
1

だが、私はこの構造体を持っているとしましょう:カスタムブレース初期化子

struct MyStruct { 
    int field1; 
    char *field2; 
    MyStruct(int a, char* b): field2(b) { 
     field1 = doStuff(a); 
    } 
    MyStruct(int a): MyStruct(a, nullptr) {} 
    ~MyStruct(); 
} 

を私の知る限り、私はいくつかのコンストラクタを持っているように、これは集計ではありません知っています。暗黙的にこの中に(最初の1適切なコンストラクタを呼び出し

MyStruct x = { 1, "string" }; 

:私が達成したい何

は、このようなコードを使用して意味し、カスタムの方法で中括弧初期化子を使用することです場合)。

は、どのような方法で、このことは可能ですか?

+0

[initializer_list](http://en.cppreference.com/w/cpp/utility/initializer_list)std::stringなると使用するには? BTW ...この特別なケースでは、[default argument](http://en.cppreference.com/w/cpp/language/default_arguments)を使用してコードを減らすことができます。 – user1810087

+3

'char *'の代わりに 'const char *'だけを使うと、そのままコンパイルされます。質問はなんですか? – SergeyA

答えて

7

あなたはほぼあります。 MyStruct x = { 1, "string" };は、コピーリストの初期化と呼ばれます。それはあなたの問題は、"string"const char*に減衰することができますconst char[N]ている間、あなたのコンストラクタはchar*を取ることはないブレース-INIT-リストから供給されたパラメータ

で利用可能なコンストラクタからMyStructを構築しようとしますa char*。それでは

MyStruct x = { 1, "string" }; 

が動作する

struct MyStruct { 
    int field1; 
    const char* field2; 
    MyStruct(int a, const char* b): field2(b) { 
     field1 = a; 
    } 
    MyStruct(int a): MyStruct(a, nullptr) {} 
    ~MyStruct() {} 
}; 

を変更するものを作ります。あなたがしたい場合は、field2を変更することができ、このもう少し防弾は

struct MyStruct { 
    int field1; 
    std::string field2; 
    MyStruct(int a, const std::string& b): field1(a), field2(b) {} 
    MyStruct(int a): MyStruct(a, "") {} 
    ~MyStruct() {} 
}; 
+0

'field2'を変更可能にする必要がある場合は、' std :: string'を使うか、手動で文字列をコピーする必要があります。 'const'を必要としなくても、' std :: string'やC++ 17 'std :: string_view'を使うべきでしょう。 –

+0

@DanielH良いことは 'string_view'です。これは不変なので、 'const char *'だったので、重要でないと思ったのでコピーしませんでした。私は間違っていた! 'field1'も定数であれば、明らかにするだけです(そして、私はcost-constructorで' const int a'を持っています)、すべてが動作し続けますか? – Fylax

+2

'const'値で' const '以外の変数を初期化できます。ここでは、 'const *'へのポインタを使って、非コンストラクタへのポインタを初期化することができないということです。なぜなら、作成されたポインタを通して値を変更できるからです。 –

関連する問題