2012-06-04 1 views
8

Visual Studio 2010 C++で次のコードに問題があります。オブジェクトジェネレータ呼び出しのr値参照にコピーコンストラクタが必要なのはなぜですか?

makeA()はC++でちょうどオブジェクト生成イディオムである

#include <stdio.h> 

struct A{ // 7th line 
    A() {} 
    A(A &&) {printf("move\n");} 
    ~A() {printf("~A();\n");} 
private: 
    A(const A &) {printf("copy\n");} // 12th line 
}; 

A makeA() 
{ 
    return A(); 
} 

int main() 
{ 
    A &&rrefA(makeA()); // 22nd line 
    return 0; 
} 

エラーメッセージ

2>d:\test.cpp(22): error C2248: 'A::A' : cannot access private member declared in class 'A' 
2>   d:\test.cpp(12) : see declaration of 'A::A' 
2>   d:\test.cpp(7) : see declaration of 'A' 
2> 

(STD :: make_pairのように)私はmakeA()は両方ともA()コンストラクタを呼び出すことを期待します(A & &)のコンストラクタ、makeA()を呼び出すための22行目、それ以外のものはありません。 (RVOなしの場合) コンパイラはA(const A &)コンストラクタにアクセスする必要はありませんか?

コードに何が問題なのか教えていただけますか?

g ++の最新バージョンでは、 'g ++ -std = C++ 0x'と 'g ++ -std = C++ 0x -fno-elide-constructors'はエラーなしでコードをコンパイルします。

+0

'A()'を{{} 'に変更してみてください。これは次のようなものです:http://stackoverflow.com/questions/7935639/can-we-return-objects-having-a-deleted-private -copy-move-constructor-by-value-fr – Pubby

+0

@Pubby良いリンクですが、どういうわけか違う問題だと思います。 'A makeA(); 'のままにするコード内でのみmakeA()の本体を他のファイルに移動すると、前述の変更が不可視になります。 22行目がなければ、コードはコンパイルされます。 makeA()関数の問題ではないと思います。 – kcm1700

+1

99%これはコンパイラのバグです。 [MS Connect](https://connect.microsoft.com/VisualStudio/)のバグレポートを投稿し、ここにリンクを投稿してください。 – ildjarn

答えて

4

これはオプティマイザのバグです。コンパイラは移動を逃げようとするが、コピーコンストラクタを必要とするようにプログラムされているだけで、コピーコンストラクタが存在していなければならない。

このエラーの修正内容は何であるかはわかりませんが、SP1で修正されている可能性があります。

+0

VC++ 2010 SP1では修正されていません。多分VC11で? – ildjarn

+1

私はVS 2012 RCをインストールし、コードの動作を確認しました。 VS2012で修正されました。ありがとうございました。 – kcm1700

+0

コピーコンストラクタが定義されていない場合でもうまく動作しますが、まだ一般公開されています。 – Puppy

関連する問題