2012-11-17 20 views
10

Lo standard C++ 11 dice qualcosa sui sindacati basati su modelli? (Non riesco a trovare nulla in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf, ma io non l'ho letto che con attenzione.)Unioni temporizzate in C++ 11

ho

template<typename T> 
union u { 
    T a; 
    char b; 
}; 

template<typename T> 
u<T> make_u(T t) { 
    return { .a = t }; 
} 

int main() { 
    return make_u<int>(1).a; 
} 

Questo codice fa sì icpc -std=c++11 dire error: a designator into a template-dependent type is not allowed, g++ -std=c++0x dire error: expected primary-expression before ‘.’ token, e g++ -std=c++11 (versione 4.8.0 (sperimentale)) per dire internal compiler error: in lookup_field_1, at cp/search.c:387. Posso aggirare questo sostituendo { .a = t } con t. Tuttavia, non potrei farlo per campi che non sono il primo membro del sindacato. C'è un modo per scegliere un membro diverso dal primo in un'unione basata su modelli, in cui il membro pertinente dipende dal modello? (Potrei, naturalmente, dichiarare un'unione nello stack e impostare il membro uguale al valore desiderato. Ma non è possibile farlo in un elenco di inizializzazione o in una funzione constexpr.)

+0

Domanda generale sull'unione basata sui modelli: http://stackoverflow.com/q/20743582/1147772 – Drax

risposta

13

La sintassi { .a = t } è un'estensione GNU non standard, quindi la sua interazione con altre funzionalità C++ non rientra nell'ambito dello standard C++.

Soluzione: scrivere di serie C++:

u<T> make_u(T t) { 
    u<T> r; 
    r.a = t; 
    return r; 
} 

EDIT: per quanto ne so, in C++ 11, si può dare al vostro sindacato un costruttore (un constexpr se vi piace) che fa l'inizializzazione è necessario. Esempio: http://ideone.com/s4GHjU