2012-06-04 11 views
8

Występują problemy z następującym kodem programu Visual Studio 2010 C++.Dlaczego odwołanie do r-wartości do wywołania generatora obiektu wymaga konstruktora kopiowania?

makea() jest właśnie przedmiotem generator idiom w C++ (jak std :: make_pair)

#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; 
} 

Komunikat o błędzie

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> 

Spodziewam makea(), aby wywołać zarówno A() Konstruktor i A (A & &) konstruktora i 22 linii do wywołania makeA() i nic poza tym. (Jeśli bez RVO) Kompilator nie powinien wymagać, aby konstruktor A (const A &) był dostępny, czy nie?

Czy możesz mi powiedzieć, co jest nie tak z kodem?

W najnowszej wersji g ++, "g ++ -std = C++ 0x" i "g ++ -std = C++ 0x -fno-elide-constructors" kompiluje kod bez żadnego błędu.

+0

Spróbuj zmienić 'A()' na '{}' - może to być związane z tym: http://stackoverflow.com/questions/7935639/can-we-return-objects-having-a-deleted-private -copy-move-constructor-by-value-fr – Pubby

+0

@Pubby Dobry link, ale myślę, że to jakiś inny problem. Pozostawiając 'A makeA(); ' tylko w kodzie i przeniesienie ciała makeA() do drugiego pliku powinna spowodować niewidoczną wspomnianą zmianę. Bez 22. linii kod się kompiluje. Myślę, że to nie problem funkcji makeA(). – kcm1700

+1

99% pewności, że jest to błąd kompilatora. Opublikuj raport o błędzie w [MS Connect] (https://connect.microsoft.com/VisualStudio/) i umieść tutaj link do niego. – ildjarn

Odpowiedz

4

To błąd w optymalizatorze. Kompilator próbuje usunąć ruch, ale jest zaprogramowany tylko do usunięcia konstruktora kopii, który wymaga, aby konstruktor kopiowania istniał w pierwszej kolejności.

Nie pamiętam, jaka (jeśli w ogóle) poprawka dla tego błędu, ale mogła zostać naprawiona w SP1.

+0

Nie ustalono w VC++ 2010 SP1. Może w VC11? – ildjarn

+1

Zainstalowałem VS 2012 RC i sprawdziłem działający kod. Naprawiono go w VS2012. Dziękuję Ci. – kcm1700

+0

Och, działa, jeśli konstruktor kopii nie jest zdefiniowany, jak sądzę, ale nadal publicznie dostępny. – Puppy

Powiązane problemy