2015-11-23 12 views
5

In base alle risposte che ho ottenuto here, il codice riportato di seguito è mal formato, nonostante il fatto che lo sia clang e vs2015.Tentativo di comprendere [class.qual]/2 nello standard C++

#include <iostream> 
class A { 
public: 
    A() { std::cout << "A()" << '\n'; } 
}; 

int main() 
{ 
    A::A(); 
} 

Tuttavia il codice qui sotto sembra funzionare in tutti e 3 i compilatori (vedi live example). AFAICT, secondo [class.qual/2] il codice è mal formato. O mi sto perdendo qualcosa qui?

#include <iostream> 
struct B { B() { std::cout << "B()" << '\n'; } }; 
struct A : public B { }; 
int main() 
{ 
    A::B(); 
} 

Inoltre, secondo [class.qual]/2, il codice sotto è ben formata e in questo caso, tutti i 3 compilatori produrre l'output previsto (vedi esempio here).

include <iostream> 
struct B { B() { std::cout << "B()" << '\n'; } }; 
struct A : public B { using B::B; A() { std::cout << "A()" << '\n'; } void f() { B(); } }; 
int main() 
{ 
    A a; 
    a.f(); 
} 

uscita:

B() 
A() 
B() 

Ma mi piacerebbe sapere qual è l'utilità di una dichiarazione using denominazione un costruttore, come quello (using B::B;) al precedente classe di A. Si noti che questa dichiarazione d'uso è totalmente irrilevante in questo caso, non importa se B è una classe base di A, oppure no.

risposta

3

Penso che il tuo secondo campione sia ben formato. La regola in [class.qual]/2 indica che il nome fa riferimento al costruttore se il nome specificato dopo lo identificatore di nome nidificato quando viene cercato in C è il nome di classe immesso di C. Nel caso di A::B, il nome specificato dopo l'identificatore nome-nidificato è il nome-classe-immesso di B (visibile a causa dell'ereditarietà), non A. In questo caso, A::B identifica in modo univoco un tipo, A::B() crea un'istanza temporanea B.

Uso-dichiarazioni di naming costruttori possono essere utili per promuovere i costruttori della classe base che prendono argomenti:

struct B { B(int a) { std::cout << "B " << a << '\n'; } }; 
struct A : public B { using B::B; }; 
int main() 
{ 
    A a{1}; //would not be valid without the using-declaration 
} 
+0

Il tuo esempio di cui sopra sembra confermare quello che stai dicendo. Ma potresti fornire una citazione dallo standard che supporta questa costruzione. Non ho mai visto questa costruzione prima. – Belloc

+0

Lo standardese è un po 'lungo per averlo inserito nella mia domanda, ma probabilmente vorrai dare un'occhiata a '[class.inhctor]' – TartanLlama

+0

Dopo un rapido sguardo su [class.inhctor] devo essere d'accordo con te. Sembra rispondere alla mia seconda domanda (+1). Ma non sono ancora convinto della mia prima domanda. – Belloc

Problemi correlati