2015-10-16 11 views
16

Ich fand es sehr seltsam, dass das folgende Programm noch gut zusammengestellt trotz des Standardkonstruktor seiner private (4.8.1 g ++):= Standard ignoriert Zugriffsspezifizierer?

class A{ 
private: 
    A() = default; 
    A(const A&) = default; 
}; 

int main(){ 

    A a; 

} 

Eigentlich von 8.4.2 [2] der Norm (N3242)

Eine explizit voreingestellte Funktion kann nur dann als constexpr deklariert werden, wenn sie implizit als constexpr deklariert wurde. Wenn es ausdrücklich auf seiner ersten Erklärung vorbelegt ist,

- wird es öffentlich,

..........

Was genau ist der Zweck, für den Standard Spezifizierer Ignoriere die Zugriffsspezifikation? Ich denke, das könnte zu einem Schnittstellenproblem führen, das durch den Klassendesigner nicht in Frage gestellt wird, der nicht wollte, dass Benutzer Standardwerte erstellen, sondern den Standardkonstruktor in der Implementierung benötigten. Ich dachte, das liegt vielleicht daran, dass der Standardkonstruktor normalerweise public ist und die default daher darauf abzielt, sie zu replizieren - aber das beantwortet nicht, warum =default auf dem Kopierkonstruktor die private Spezifikation nicht ignoriert.

class A{ 
private: 
    A() = default; 
    A(const A&) = default; 
}; 

int main(){ 

    A a; 
    A b(a); //error: constexpr A::A(const A&) is private 

} 

Eigentlich kann ich nicht von der Norm sehen, wo es erwähnt, dass explizit vorgegeben copy/move Bauer/Zuordnungen nicht public gemacht werden.

Antwort

15

Dies ist ein gcc-Fehler. Bug 57913 enthält ein Beispiel fast identisch mit Ihrem. Bug 56429 enthält Links zu mehreren verwandten Fehlerberichten, von denen bug 54812 in gcc 4.9 behoben wurde, was in der Tat Ihren Code zurückweist.

error: 'constexpr A::A()' is private 

Live demo

+0

Alrighty, danke. Ich glaube, ich habe das Zitat aus dem Standard missverstanden. Es war völlig spezifisch für den Kontext von "conexpr" erklärten Funktionen. – Silversonic

+3

@Silversonic Welche Version des Standards zitieren Sie? Ich kann nicht finden, dass der * öffentliche Teil in N3337 oder N4296 ist. – Praetorian

+0

Ich schaute auf N3242. Ich dachte, das wäre das Beste, wenn ich mit C++ 11 arbeite? Sollte ich zu N3337 wechseln? – Silversonic