2015-09-25 8 views
18

VS2015 C++コンパイラをテストしているときに、defaultキーワードで奇妙なバグがありました。私が行う場合: 'ダミー::ダミー(constのダミー&)':ダミー」の宣言を参照してください。削除機能
ノートを参照しようとVS2015の `default`キーワードを扱う際に起こりうるバグC++

struct Dummy 
{ 
    Dummy() = default; 
    Dummy(const Dummy &) = delete; 
}; 

int main() 
{ 
    const Dummy& ref = Dummy(); 
    return 0; 
} 

は私が

エラーC2280を取得します: :ダミー」

しかし、私は空のコンストラクタを使用している場合

struct Dummy 
{ 
    Dummy() {} 
    Dummy(const Dummy &) = delete; 
}; 

int main() 
{ 
    const Dummy& ref = Dummy(); 
    return 0; 
} 

コードがコンパイルされます。 g++またはclangで最初の例を実行するとエラーは発生しません。

なぜVS2015でデフォルトのコンストラクタを使用すると、g ++やclangにないコピーコンストラクタを使用しようとしますか?

+0

あなたは 'const Dummy&r2 {Dummy()};'から何を得るのですか? –

+0

関連項目:[コピー/移動の削除と明示的に削除されたコピー/移動コンストラクタ](http:// stackoverflow。com/questions/20589622) –

+0

こちらをご覧くださいhttp://stackoverflow.com/questions/31264984/c-compiler-error-c2280-attempting-to-reference-a-deleted-function-in-visual –

答えて

9

それはコピーコンストラクタを呼び出すことはできませんconst参照に一時的に割り当て、間違いなくC++ 11では

VS 2015のバグですが、VS 2015はありません。

あなたはVS 2013、2015、gccと打ち鳴らす上でコンパイル

#include <iostream> 

struct Dummy 
{ 
    Dummy() = default; 
    Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; } 
    void test() const { std::cout << "test" << std::endl; } 
}; 

int main() 
{ 
    const Dummy& ref = Dummy(); 
    ref.test(); 
    return 0; 
} 

でそれを確認することができます。クラスコンストラクタが= defaultと定義されている場合は、VS(任意のバージョン)のみがコピーコンストラクタを呼び出します。

私はまだ2015年にVSのcompiilerが誤っこのため、古いC++ 03標準規則(C++ 03の8.5.3.5)を使用しますと思う:初期化子式はT2 Aと、右辺値である場合

をクラス型、および 「CV1 T1が」基準互換「CV2のT2」参照は、以下のいずれかの方法で を結合しているとされ(選択は、実装定義である):

- 参照はに結合していますrvalue(3.10参照)で表されるオブジェクト、またはそのオブジェクト内のサブオブジェクトに適用されます。

- 一時的なタイプ "cv1 T2" [sic]が作成され、rvalueオブジェクト全体を一時的にコピーするコンストラクタが呼び出されます。 の参照は、一時的にまたは 一時的にサブオブジェクトにバインドされています。

コピーを作成するために使用されるコンストラクタは、コピーが実際に行われたかどうかにかかわらず、呼び出し可能な でなければなりません。

第2の方法を選択しました。空のユーザー定義コンストラクタ({})に対してこれを修正しましたが、デフォルトの(= default)コンストラクタではこれを忘れていました。

PS。 Bug on MS Connect(投票してください)

+0

S.T.L.の回答:https://twitter.com/StephanTLavavej/status/648949525684465664 – vladon

関連する問題