2012-06-06 5 views
5
struct POD { int i, j; };  
class A { 
    POD m_pod; 
public: 
    A() : m_pod({1,2}) {} // error 
    A() : m_pod(static_cast<POD>({1,2})) {} // error 
    A() : m_pod((POD) {1,2}) {} // ok! 
}; 

Lo vedo in un vecchio codice di produzione compilato con g++34, fino a quel momento non conosco questa funzione.
È una funzionalità specifica di g++? In caso contrario, perché è necessario il typecasting e questo è consentito solo al cast in stile C?Perché un typecasting in stile C è obbligatorio durante l'inizializzazione di un dato POD nell'elenco degli inizializzatori?

+0

La mia ipotesi è '{1,2}' non è un tipo di POD e un 'reinterpret_cast' sta accadendo. –

risposta

4

La sintassi che stai utilizzando non è solo per gli elenchi di inizializzatori, è per qualsiasi inizializzazione di tipi di classe al di fuori delle loro dichiarazioni. Ad esempio:

POD p; 
p = (POD) {1, 2}; 

Questi sono chiamati letterali composti; sono stati aggiunti a C in C99. Non sono effettivamente supportati in C++; GCC li consente in C++ (e C89) come extension. C++ 11 adds the syntax:

p = POD({1, 2}); 

o nel vostro caso:

A() : m_pod(POD({1,2})) {} 
+0

Inoltre non sapevo che GCC permettesse 'POD p; p = (POD) {1, 2}; 'sintassi. Tutte le risposte sono buone; accettando questo per informazioni utili riguardanti le estensioni. – iammilind

6

In realtà la seguente sintassi non è consentito dalla C++ standard (sia C++ 03, e C++ 11):

A() : m_pod((POD) {1,2}) {} // ok! 

Dal GCC compila questo, si tratta di un'estensione GCC.

Se si compila con -pedantic opzione, dà questo avvertimento:

pod.cpp: 8: 29: avvertimento: ISO C++ proibisce composti-letterali


In C++ 11, è possibile scrivere questo:

A() : m_pod{1,2} {} 

Demo: http://ideone.com/XaO4y

O semplicemente questo:

class A { 
    POD m_pod {1,2}; //in-place initialization 
public: 
    A() {} 
}; 

Ideone non supporta questo però.