2015-03-12 18 views
13

Si consideri il seguente codice:È possibile creare un alias del modello?

template< template< typename ... > class ... Ts > 
struct unite 
{ 
    template< typename ... T > 
    struct type 
     : Ts< T ... > ... 
    { }; 
}; 

// This does not work as ::type does not name a type, but a template: 

// template< template< typename ... > class ... Ts > 
// using unite_t = typename unite< Ts ... >::type; 

template<typename> struct debug_none {}; 
template<typename> struct debug_cout {}; 

template< typename ... > struct raise_demangled {}; 
template< typename ... > struct raise_specialized {}; 

template< typename, typename = int > struct match_default {}; 

template< template< typename ... > class Control > 
void f() 
{} 

int main() 
{ 
    f< unite< debug_none, raise_demangled, match_default >::type >(); 

    // Is there any way to create something like unite_t which works like this: 

    // f< unite_t< debug_none, raise_demangled, match_default > >(); 
} 

Live example

Domanda: Esiste un modo per creare una sorta di "modello alias" simile a un tipo alias? (vedere unite_t nell'esempio sopra)

+1

Quindi, domanda: ho ricordato come ho scritto che ho fatto questa domanda esatta prima. Dovrei chiudere i miei http://stackoverflow.com/questions/17356487/equivalent-of-using-aliases-for-templates come duplicati di questo? O vice versa? :) – Yakk

+1

@Yakk Anche se la tua domanda è abbastanza simile e nella stessa area, non penso che sia davvero un duplicato, dato che hai cercato di sbarazzarti della parola chiave 'template' in un posto diverso. Se esiste una soluzione per uno * sarebbe *, * potrebbe * risolvere anche l'altro problema - ma sembra che non ci sia una soluzione. –

risposta

5

No, non è possibile.

using può "restituire" un tipo o una variabile. Non può "restituire" un template. Non ci sono meccanismi simili altrove.

Si può fare qualcosa di vagamente utile prendendo la convenzione che tutti i modelli non sono modelli, ma piuttosto le classi con un template<?>using apply=?; alias al loro interno (e già che ci siamo, costanti sono std::integral_constants<T,?> e puntatori sono pointer_constant<T*,?>).

Ora tutto è una classe. template s diventano solo tipi di classi (con un ::apply<?...>

L'applicazione di un insieme di tipi a un tale modello sarebbe fatto attraverso:.

template<class Z, class...Ts> 
using apply_t = Z::template apply<Ts...>; 

Quindi, con un modello di "nativo" Z, è' d fare Z<Ts...>. Con questi modelli "indiretti", faresti apply_t<Z, Ts...>.

Con questa convenzione, un modello using alias può restituire un modello indiretto. Se il resto del codice segue la Convenzione di chiamare sempre apply_t per applicare un modello e hai indiretto tutti gli altri modelli che scrivi, abbiamo finito.

Questo è brutto.

+0

Esiste una proposta per risolvere questo problema? – Brian

+0

@Brian non che io sappia. La necessità di avere tali alias è discutibile, dal momento che solo l'uso relativamente avanzato di C++ lo richiede, quindi forse nessuno si è preoccupato. – Yakk

+0

Grazie per la tua risposta, probabilmente la contrassegnerò come "accettata" presto - il "No, non puoi" -part :) Purtroppo l'alternativa/work-around suggerita non può essere realmente utilizzata nel mio caso in quanto renderebbe il interfaccia (che è visibile verso l'utente) ancora più complicata/brutta. In realtà sto considerando di abbandonare questa idea invece di confondere gli utenti. –