2016-03-11 13 views
20

Durante il refactoring di un codice C++ 11, mi sono imbattuto in una cosa strana. Vale a dire, sembra essere impossibile definire una (const, volatile o const volatile) classe base CV-qualificata, ad esempio:Classi di base qualificate CV in C++

struct A { int a = 0; }; 
struct B: A const {}; // Error here with Clang and GCC! 

Tuttavia, i seguenti compilazioni senza errori:

struct A { int a = 0; }; 
using AC = A const; 
struct B: AC {};  // NO ERROR HERE!? Qualifiers are ignored. 
int main() { 
    B b; 
    b.a = 42;   // NO ERROR modifying a field of const base. 
    return b.a; 
} 

ho due domande:

  1. Cosa negli standard C++ proibisce di definire una classe base qualificata CV, se non del tutto?
  2. Perché compila il secondo esempio?

PS: Dal momento che si tratta di un linguaggio di avvocato domanda, si prega di fornire riferimenti alla norma C++.

+4

Si può ancora utilizzare la composizione const ... – Jarod42

+0

Aggiungendo a ciò jarrod42 detto, che cosa significa "B è un' const' A" significa? Anche B 'const', allora? – rubenvb

risposta

21
  1. La grammatica lo proibisce. Le classi di base sono specificate con la produzione di base di base specificata all'inizio della sezione 10 dello standard. Alla fine si risolve base-tipo-specificatore, che è classe-o-decltype, ovvero un costrutto decltype o un nested-nome-specificatore [opt] nome-classe. Nota che questo non lascia spazio a un cv-specificatore.

  2. Il nome typedef si adatta alla grammatica. 9.1/5 dice "Un typedef-name che identifica un tipo di classe, o una sua versione cv-qualificata, è anche un nome di classe." Il const è semplicemente ignorato.

  3. Il const viene semplicemente ignorato. I sottooggetti di classe base non possono essere const da soli. 9.1/5 dice "Se viene usato un typedef-name che nomina un tipo di classe qualificata cv dove è richiesto un nome-classe, i qualificatori cv vengono ignorati."

+0

È anche rilevante per la domanda 1 che 9.1/5 dice anche che "A * typedef-name * (7.1.3) che identifica un tipo di classe, o una versione qualificata cv, è anche un * nome-classe *. " Le regole grammaticali nello standard non contengono esplicitamente * typedef-name * sotto * class-name *. Per qualche motivo questo è solo dato una nota in appendice. – jotik

7

In realtà è l'intero oggetto creato che è const o non const, le classi non sono qualificate per il cv.

In using AC = A const; il const viene semplicemente ignorato quando viene utilizzato per l'ereditarietà.

+0

Sì, ho capito, ma perché? – jotik

+0

'AC' è in realtà' A const' e non solo 'A': [Demo] (http://coliru.stacked-crooked.com/a/6cf24bd593d2f895). – Jarod42

+0

@jotik I padri che definiscono non hanno visto alcun uso per un oggetto partizionato cv, non penso che sia più dietro questa decisione di quella – Jojje