2015-05-08 5 views
8
vorgesehen ist

Ich schätze die C++ 11-Standard schreibt vor:Visual Studio 2013 nicht den Kopierkonstruktor löschen, wenn eine benutzerdefinierte Bewegung Konstruktor

Wenn die Klassendefinition explizit keine Kopie Konstruktor deklarieren, Eins wird implizit erklärt. Wenn die Klassendefinition einen Move-Konstruktor oder Move-Zuweisungsoperator deklariert, wird der implizit deklarierte Copy-Konstruktor als gelöscht definiert; Andernfalls wird als Standard definiert.

(tatsächlich kopiert von here)

Der folgende Code:

#include <iostream> 

struct C 
{ 
    int x = 1; 

    C() 
    { 
    } 

    C(C&&) 
    { 
    } 
}; 

int main() 
{ 
    const C c; 
    C c2(c); 

    std::cout << c.x << " " << c2.x << std::endl; 

    return 0; 
} 

nicht kompiliert auf gcc 4.9.0, sondern kompiliert nur gut auf Visual Studio 2013 (Compiler Version 18.00.21005.1 for x86). Ist das eine weitere Visual Studio Verletzung des Standards, oder mache ich diesmal etwas falsch? Wenn dies eine Verletzung des Standards ist, gibt es einen Tracking-Fehler oder eine Quelle, in der dieses Verhalten dokumentiert ist?

+0

Can Sie senden die Kompilierungsfehlermeldung (en)? Wäre nützlich ... – floppy12

+0

@ floppy12: http://ideone.com/yhqPBb Das ist gcc 4.9.2 in C++ 14-Modus. Ihr gcc wird wahrscheinlich das gleiche tun. Jedenfalls ist es nicht das Vorhandensein eines Fehlers mit gcc das Problem, aber seine Abwesenheit mit VS. – gd1

Antwort

5

Sie machen nichts falsch, und Ihre Interpretation des Standards ist korrekt. Visual C++ 2013 implementiert diese Regeln tatsächlich nicht ordnungsgemäß.

Ein relevanter Bericht Fehler ist hier:

Default copy constructor is generated even when a custom move constructor is defined [c++11]

Es als Won't Fix markiert ist und der Kommentar aus dem Entwicklungsteam:

Visual Studio 2013 in die Tat nicht implementiert vollständig die C + +11 Regeln steuern spezielle Elementfunktionen und verschieben Operationen. Wir werden eine Fehlerbehebung für diesen Fehler in der nächsten Hauptversion von Visual Studio enthalten.

Die gute Nachricht ist, dass die Dinge in Visual C++ 2015 RC ordnungsgemäß zu funktionieren scheinen. Ich habe gerade überprüft, dass Ihr Code sowohl Compiler- als auch IntelliSense-Fehler auslöst. Der Compiler Diagnose ist:

error C2280: 'C::C(const C &)': attempting to reference a deleted function 

(. Von dem, was ich in den letzten Monaten getestet haben, MSVC14 als ziemlich gut C++ Compiler Gestaltung bis - viele Standard-Compliance-Probleme behoben wurden)

+0

Das sind in der Tat gute Nachrichten * für die Zukunft *, aber vorläufig ist es ein großes Problem. Wenn Sie den Standard brechen müssen, ist es in Ordnung, wenn Sie es tun, indem Sie die Funktionalität X oder Y nicht bereitstellen, aber wenn Sie die Hälfte davon bereitstellen, können Sie ganze Projekte in ernste Gefahr bringen. Eine Kopie passiert, mein Fehler könnte eine Katastrophe sein. – gd1

+1

@ gd1 Ja, ich fühle deine Schmerzen. Aber an Orten, wo das Verhindern von Kopien so wichtig ist, dass es das Projekt beschädigen oder zerstören könnte, würde ich sagen, dass es eine gute Idee ist, den Kopierkonstruktor (und wahrscheinlich auch den Kopierzuweisungsoperator) explizit "zu löschen". Das mache ich bisher in Visual C++ 2013, und dieser Teil funktioniert gut. – bogdan

Verwandte Themen