2016-05-29 1 views
0

コピーまたは移動コンストラクタを持たない別のクラスの配列メンバ( "C配列")を持つクラスを作成したいと思います。残念なことに、コンパイラは私に内部クラスの移動コンストラクタが必要であることを伝えるエラーメッセージを表示します。私は、コンパイル時に指定されたサイズの配列が必要な理由を理解していません。私にとってさらに奇妙なのは、配列がクラスメンバではなく自動スタック変数である場合、コンパイラは不平を言っていないということです。 次のコードは私の問題を示しています。これはコンパイルされ、最初の行(つまり、コンストラクタを使用して)で期待通りに実行されます。出力には、ムーブコンストラクタが呼び出されないことが示されます。しかし、最初の行がコメントアウトされた状態では、27行目(配列は別の構造体のメンバ変数)にエラーメッセージが表示されますが、37行目(配列変数は配列変数)はコンパイルされます。 この例のように、初期化子リストを使用してタイプAの配列要素を構築したいとします。クラスの配列メンバーに必要な移動

#define WITH_MOVE_CTOR 

#include <iostream> 
using namespace std; 

struct A { 
    A(int i, bool b) : mi(i), mb(b) 
    { } 
    A(A&&s) 
#ifdef WITH_MOVE_CTOR 
    : mi(s.mi),mb(s.mb) 
    { cout << s << "move ctor called\n"; } 
#else 
    = delete; 
#endif 
    A() = delete; 
    A(const A&) = delete; 
    A& operator=(const A&) = delete; 
    friend ostream & operator<<(ostream & in, const A&a) 
    { return in << a.mi << "," << a.mb; } 
    void foo() const { cout << *this << " foo called\n"; } 
    int mi; 
    bool mb; 
}; 

struct CA { 
    CA() : m({{1, true},{2, false}}) {} 
    CA(const A&) = delete; 
    CA(A&&) = delete; 
    CA& operator=(const CA&) = delete; 
    A m[2]; 
}; 

int main() 
{ 
    cout << "C-array:\n"; 
    A ca[2] = {{1, true},{2, false}}; 
    ca[1].foo(); 

    cout << "C-array in struct:\n"; 
    CA sca; 
    sca.m[1].foo(); 
    return 0; 
} 

出力:それは場所に構築していますので、

C-array: 
2,0 foo() called 
C-array in struct: 
2,0 foo() called 
+2

{{1、true}、{2、false} {} ' –

+0

中括弧を省略すると問題は解決します。ありがとうございます! – Stefan

+0

@Kerrek SBコンパイラが中カッコで何をするのか説明できますか?実行時に少なくとも結果は同じです。 e。移動コンストラクタは呼び出されません。 – Stefan

答えて

1

ライン37は、静的初期化子です。だから何も動かす必要はありません。

27行目は最初に配列を割り当ててから、イニシャライザ配列を移動します。これには、移動コンストラクタが必要です。

+0

なぜですか。 37「静的な」初期化子? "静的な"記憶域タイプ指定子はないので、配列はコンパイル時に知られている配列サイズのスタックに "割り当て"なければなりません(つまり、コンパイラは配列変数なしのスタックとしてメモリを予約できます。関与する)。私も同じです。 37.実行時には、移動コンストラクタは呼び出されないことにも注意してください。 e。実際にはlで行われます。 37およびl。 27。 – Stefan

0

私はKerrek SBからCAのctor(1.37)の初期化子リストの()カッコが問題を引き起こしたことを知りました。ありがとうございました! しかし、依然として未解決な質問が残っています。lの()中括弧は何をしますか?私の例の37はコンパイラを意味しますか?実行時には、移動コンストラクターが存在するときには呼び出されないので、明らかに効果がありません。

関連する問題