2017-07-13 4 views
0

私はSTDを含むC++クラスには2つの異なるコンストラクタ::ベクトル部材を提供しようとしています:C++ブレース囲まれた初期化子リスト

class A { 

    public: 

     std::vector<int> p; 

     A (std::vector<int> i) { p = i; } 

     A (int x, int y, int z) : A ({x, y, z}) {} 
}; 

int main() { 

    A a ({1, 2, 3}); 

    A a2 (1, 2, 3); 

    return 0; 
} 

最初のコンストラクタは、[OK]を動作しますが、二番目のスロー次のエラー:

error: call of overloaded ‘A(<brace-enclosed initializer list>)’ is ambiguous 

2つの方法の違いはどちらですか?

+1

[ノート](http://coliru.stacked-crooked.com/a/72bc6715d2140911)を読むことができます。 – LogicStuff

+0

もちろん、あいまいです。 '{x、y、z}'現在の 'A'がコピー/移動される一時的な' A'か 'A'が構築される'ベクトル 'を作成できます。コンパイラはどのように選択する必要がありますか? – StoryTeller

+0

エラーが発生した場合は、必ず*完全*エラーメッセージをお読みください。何が起こっているのかを理解するのに役立つ情報のメモがしばしばあるかもしれません。 –

答えて

1

問題は、第二のコンストラクタである:

A (int x, int y, int z) : A ({x, y, z}) {} 

A ({x,y,z})の両方

  • 最初のコンストラクタを呼び出すことができるので:初期化リスト{x, y, z}std::vector<int>にキャストし、最初のコンストラクタと一致することができます。

  • 二コンストラクタ自体:


A::A(int, int, int): 
pushl %ebp 
movl %esp, %ebp 
subl $8, %esp 
// ... 
call A::A(int, int, int) // <--- recursive call 
// ... 

Which is the difference between the two methods?

最初のコンストラクタは整数の任意のベクトルを受け入れる:コンストラクタは、自分自身を呼び出すどこhereを見ることができるように。有効な構成は、たとえば次のとおりです。

A({1}); A({1, 2}); A({1, 2, 4}); A({1, 2, 3, 4, ...}); ... 

2番目のコンストラクタは3つの整数を受け入れます。有効な構造は以下のとおりです。あなたが表現A({1, 2, 3})は、両方のコンストラクタによって受け入れられているので、それがあいまいで見ることができるように(コンパイラが知ることができない、選択した決定論的な方法で)

A({1, 2, 3}); A(1, 2, 3); A{1, 2, 3}; 

+1

私は今それを見る。私は{1,2,3}が3つの整数だけを構築するのに有効であったことは知らなかった。このあいまいさを解消するために呼び出す方法を指定する方法はありますか?または、私はちょうど2番目のコンストラクタの代わりに別の関数を使用する必要がありますか? – derkomai

+1

@derkomai明示的にbraced-initリストのコンストラクタを追加することができます: 'A(std :: initializer_list i):p(i){}' – Ap31

+0

これはちょうど私が探していたものです! – derkomai

関連する問題