2015-10-16 16 views
16

Znalazłem to dość dziwne, że następujący program nadal opracowywane w porządku mimo konstruktor domyślny jest private (4.8.1 g ++):= domyślnie ignoruje specyfikator dostępu?

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

int main(){ 

    A a; 

} 

Właściwie od 8.4.2 [2] standardu (N3242)

Funkcja jawnie domyślna może być zadeklarowana jako constexpr tylko wtedy, gdyby została domyślnie zadeklarowana jako constexpr. Jeśli jest wyraźnie wywiąże się ze swoim pierwszym oświadczeniu

- powinno być publiczne,

..........

Czym dokładnie jest cel dla domyślnego specyfikatorem do zignorować specyfikację dostępu? Czuję, że może to spowodować problem z interfejsem, który nie jest uzasadniony przez projektanta klas, który nie chce, aby użytkownicy tworzyli wartości domyślne, ale potrzebował domyślnego konstruktora w implementacji. Pomyślałem, że może dlatego, że domyślnym konstruktorem jest zwykle public, a więc default ma na celu jego replikację - ale to nie odpowiada, dlaczego =default na konstruktorze kopiowania nie ignoruje specyfikacji private.

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

int main(){ 

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

} 

Właściwie nie widzę od standardu, gdzie wspomina jawnie, domyślnie copy/move konstruktorów/zadaniach nie są dokonywane public.

Odpowiedz

15

To jest błąd gcc. Bug 57913 zawiera przykład prawie identyczny z twoim. Bug 56429 zawiera linki do kilku powiązanych raportów o błędach, z których bug 54812 zostało naprawione w gcc 4.9, co faktycznie odrzuca twój kod.

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

Live demo

+0

W porządku, dzięki. Chyba źle zrozumiałem ten cytat ze standardu. Było to całkowicie specyficzne dla kontekstu funkcji deklarowanych przez "constexpr". – Silversonic

+3

@Silversonic Którą wersję standardu cytujesz? Nie mogę znaleźć * to będzie część publiczna * w N3337 lub N4296 – Praetorian

+0

Patrzyłem na N3242. Sądziłem, że najlepiej byłoby sprawdzić, czy pracuję z C++ 11? Czy powinienem zamienić się na N3337? – Silversonic