2012-03-15 17 views
5

Gli argomenti del modello predefinito possono essere utilizzati per simulare alias per espressioni di tipi complessi in una dichiarazione modello. Per esempio:È possibile simulare argomenti modello predefiniti in specializzazioni parziali?

template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type 
struct foo { ... X, Y, Z ... }; 

Tuttavia, specializzazioni parziali potrebbero non avere argomenti di template di default ([C++11: 14.5.5/8]), quindi questo trucco non funziona. Potresti chiederti perché un typedef nel corpo non funziona, e la risposta è che gli alias devono essere nel campo di applicazione prima del corpo della classe, al fine di eseguire l'abilitazione condizionale; ad esempio:

template <typename T, typename Enable = void> 
struct bar; 

// Wishful thinking: 
template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type> 
struct bar <std::vector<X>, 
      typename enable_if< 
       some_condition<X, Y, Z> 
      >::type> 
    { ... }; 

Il modo in cui ho lavorato intorno ad essa sta usando un tipo ausiliario:

template <typename X> 
struct bar_enabled { 
    typedef typename do_something_with<X>::type Y; 
    typedef typename some_other_thing_using<X, Y>::type Z; 
    static const bool value = some_condition<X, Y, Z>::value; 
}; 

template <typename X> 
struct bar <std::vector<X>, 
      typename enable_if_c< 
       bar_enabled<X>::value 
      >::type> 
    { ... }; 

ma per vari motivi (tra i quali volendo evitare un tipo separato, il che complica quello che sto facendo), spero che esista una soluzione migliore. Qualche idea?

+1

predefinite non simulano nulla. Forniscono valori predefiniti. –

+3

Per il record, "L'elenco dei parametri del modello di una specializzazione non deve contenere valori di argomento modello predefiniti" '[C++ 11: 14.5.5/8]' –

+0

@LightnessRacesinOrbit, intendi far notare che questo problema non ha cambiato in C++ 11, o qualcos'altro? – ajg

risposta

3

Forse si può attaccare la distinzione in una classe di base: argomenti

template <typename X, typename Y, bool> 
struct BaseImpl    { /* ... */ }; 

template <typename X, typename Y> 
struct BaseImpl<X, Y, true> { /* ... */ }; 

template <typename X, typename Y = typename weird_stuff<X>::type> 
struct Foo : BaseImpl<X, Y, some_condition<X, Y>::value> 
{ 
    // common stuff 
}; 
Problemi correlati