2016-04-06 5 views
1

私はコンパイラを持っている:
G ++(Ubuntuの〜14.04.1 4.8.4-2ubuntu1)4.8.4
のMicrosoft Visual Studioの2015年版14.0。 (ビジュアルC++ 2015)C++ 11グラム++エラー:削除された機能の使用

ソースコード:

#include <queue> 

class C 
{ 
}; 


class B 
{ 
public: 
    // assignment and copy prohibited 
    B(const B&) = delete; 
    B& operator=(const B&) = delete; 

    B(int v1, int v2) : m_V1(v1), m_V2(v2) {} 

private: 
    int m_V1; 
    int m_V2; 
    std::queue<C> m_Queue; 
}; 

class A 
{ 
public: 
    // assignment and copy prohibited 
    A(const A&) = delete; 
    A& operator=(const A&) = delete; 

    A(int p1, int p2) : arrB{ {p1+1, p2+2}, {p1+3, p2+4}, {p1+5, p2+6} } { } 

private: 
    B arrB[3]; 
}; 

1)私は

std::queue<C> m_Queue; 

で++グラム使用している場合は、私は次のエラーを取得:I場合)

make 
g++ -std=c++11 -c test.cpp 
test.cpp: In constructor ‘A::A(int, int)’: 
test.cpp:29:70: error: use of deleted function ‘B::B(const B&)’ 
    A(int p1, int p2) : arrB{ {p1+1, p2+2}, {p1+3, p2+4}, {p1+5, p2+6} } { } 
                    ^
test.cpp:11:3: error: declared here 
    B(const B&) = delete; 
^
make: *** [test.o] Error 1 

2 g ++を使って行をコメントしてください。

//std::queue<C> m_Queue; 

または私はMicrosoft Visual Studio 2015で両方のバリエーション(コメント付きではなく)を使用しています。エラーは発生しません。

なぜですか?

更新:
リスト初期化は、直接リストの初期化またはコピーリストの初期化を使用しています。

8.5.4 List-initialization
1 List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called an initializer list, and the comma-separated initializer-clauses of the list are called the elements of the initializer list. An initializer list may be empty. List-initialization can occur in direct-initialization or copyinitialization contexts; list-initialization in a direct-initialization context is called direct-list-initialization and list-initialization in a copy-initialization context is called copy-list-initialization.

しかし、私は私の場合には、使用する初期設定の種類を理解していません。 - 答え

8.5.1 Aggregates [dcl.init.aggr]
1 An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause.

集合体は、配列各メンバーのコピー初期化されている:私はそれをhttp://en.cppreference.com/w/cpp/language/list_initialization

アップデート2に係る直接リスト初期化を使用しなければならないはず?
しかし、この行にコメントするときエラーなしでコンパイル理由を説明していません:

私はグラムであなたの奇妙な行動を再現することができませんでした++ B.で宣言されたキューのコメント/コメントを解除に関して提供されたコードを使用して
//std::queue<C> m_Queue; 
+0

'std :: queue m_Queue;を' B'のctors初期化子リストの中括弧で空に初期化してみてください。 –

+0

g ++ 5.2も、 'm_Queue'が存在するときにはコードを拒否し、' m_Queue'がコメントアウトされているときにはそれを受け入れます。 clang ++ 3。7は、VC++ 2015と同様に、コードを無関係に受け入れます。さらに、 'B'がI-am-being-calledノートを出力するコピーコンストラクタを与えられた場合、g ++はコードをコンパイルし、テストプログラムはこのコピーコンストラクタが' A(int p1、int p2) '。 –

+0

@NowhereMan私は試みた。それは何も変わらない。 – Elija

答えて

0

キューがコメントアウトされているかどうかにかかわらず、g ++で同じエラーが発生します。

ただし、取得しているコンパイルエラーは、自分のコードのテストで取得したものと同じです。このエラーは、Bのコピーコンストラクタを明示的に削除したために発生します。私はのコピーを持っていないので、私は推測するハザードことができますあなたの質問の後半部分に関してはhttps://stackoverflow.com/a/14543600/1456187

B(const B&) = delete;

は、詳細はこちらこの回答を参照してください。エラーメッセージは、Bのコピーコンストラクタを直接指し示しますマイクロソフトのコンパイラは便利です。私の推測では、マイクロソフトのコンパイラはBsの配列の初期化を可能にしています。しかし、これは'03仕様の時点で標準規格の面で飛んでいるように見えます。

関連する問題