2016-09-05 2 views
5

なぜ私はstd :: arrayをこのように脱塩できないのですか?なぜ私はstd :: arrayをこのように脱塩できないのですか?

#include <array> 

struct Point 
{ 
    float x; 
    float y; 
}; 

int main() 
{ 
    std::array<Point, 3> m_points { 
     { 1.0f, 1.0f }, 
     { 2.0f, 2.0f }, 
     { 3.0f, 3.0f } 
    }; 
} 

これをやって私が取得エラー:

error: too many initializers for std::array<Point, 3ul>

が、それは次のように動作します。

std::map<int, int> m1 {std::pair<int, int>{1,2}, std::pair<int, int>{3,4}}; 
    std::map<int, int> m2 {{1,2}, {3,4}}; 
:コントラスト std::map
std::array<Point, 3> m_points { 
    Point{ 1.0f, 1.0f }, 
    Point{ 2.0f, 2.0f }, 
    Point{ 3.0f, 3.0f } 
}; 

は以下の書かれた両方の方法で初期化することができ

+2

中カッコが間違っていますか? 'std :: array m_points {{{1.0f、1.0f}、{2.0f、2.0f}、{3.0f、3.0f}}}'を試してください。 [動作するように思える...](http://coliru.stacked-crooked.com/a/747be1b02cacb8e2) – ildjarn

+0

私は問題は、コンパイラが最初の例でどのような構造体を初期化したいのか分からないことだと思います。あなたが配列に型を伝えていても、 'Point'が必要なのはわかりません。 – meetaig

+0

@meetaigは私のようにも見えますが、同じ種類のコードは' std :: map'で動作します。 std :: map m {std :: pair {1,2}、std :: pair {3,4}}; 'std :: map m {1,2}を書くことができます。 、3,4}}; '違いは何ですか? – Narek

答えて

6

この宣言および初期化

std::array<Point, 3> m_points { 
     { 1.0f, 1.0f }, 
     { 2.0f, 2.0f }, 
     { 3.0f, 3.0f } 
    }; 

でコンパイラは、(内部凝集の)アレイ全体の初期化など括弧内の最初の初期化を考慮する。 std::arrayは、別の集約を含む集計です。

ライト代わり

std::array<Point, 3> m_points { 
     { 
     { 1.0f, 1.0f }, 
     { 2.0f, 2.0f }, 
     { 3.0f, 3.0f } 
     } 
    }; 
第2のケースで

std::array<Point, 3> m_points { 
    Point{ 1.0f, 1.0f }, 
    Point{ 2.0f, 2.0f }, 
    Point{ 3.0f, 3.0f } 
}; 

各イニシャライザは、内部凝集の次の要素の初期化子として順次考えられます。

この簡単なデモンストレーションプログラムを検討してください。

#include <iostream> 

struct array 
{ 
    int a[10]; 
}; 

int main() 
{ 
    array a = { { 0, 0 }, { 1, 1 } }; 

    return 0; 
} 

コンパイラは{ 0, 0 }内部配列(内部凝集体)の初期であると判定された

prog.cpp:14:33: error: too many initializers for 'array' 
    array a = { { 0, 0 }, { 1, 1 } }; 
           ^

ようなエラーを発行します。したがって、中括弧内の次のイニシャライザは、外部集約(構造体)に対応するデータメンバを持ちません。

+0

2つの中括弧を2つ追加するとなぜ問題が解決するのか全く分かりません。 – Narek

+0

@Narek、余分な中括弧(または '=')を使用すると、集約初期化が行われるためです。 – StoryTeller

+0

@StoryTellerたぶん類似の例が明らかになるでしょうか? – Narek

2

std::arrayには、std::vectorstd::mapなどの他の標準コンテナとは異なり、自動的に提供されるコンストラクタだけが明示的に定義されたコンストラクタはありません。 std::vectorでは、コンパイラが使用可能な各コンストラクタに対してと

std::vecor<Point> m_points { {1.0f,1.0f}, {2.0f,2.0f}, {3.0f,3.0f} }; 

のような構造のため、あなたの表現に一致しようとすると、コンストラクタで一致を見つけ

std::vector::vector(initializer_list<T>, const Allocator& = Allocator()); 

しかしstd::arrayと、それはの集計初期化を使用する必要があります。基本的な配列(あなたの場合はPoint[3])ですから、あなたの構造は一致しません。それを動作させるには、別のブレースペアを追加する必要があります。

std::array<Point, 3> m_points { 
    { { 1.0f, 1.0f }, 
    { 2.0f, 2.0f }, 
    { 3.0f, 3.0f } } 
}; 
+0

なぜ私はstd :: arrayの内部実装に対処しなければなりませんか?私はちょうどそれを初期化したいと思うし、それがどのように設計されているか気にしない。これがおかしいことに同意しますか? – Narek

+0

それはまったく別の、まったく異なる質問です。あなたが(最初に)質問しなかった質問に対する回答は期待しないでください。 – Walter

+0

コメントでもどちらですか? :) – Narek

関連する問題