2012-01-12 9 views
8

La domanda quasi non ha senso senza un esempio. Quindi ecco cosa sto cercando di fare.Perché utilizzare un parametro del parametro di valore integrale non consentito dopo un pacchetto di parametri di tipo in C++ 11?

In generale, C++ permette la seguente:

template<class T, class U, T t, U u> 
void func() {} 

func<char, int, 'A', 10>(); 

ma sembra che la sua estensione variadic naturale non funziona.

template<class...T, T... t> 
void func() {} 

func<char, int, 'A', 10>(); 

Sia clang che g ++ 4.7 rifiutano il codice precedente. L'errore viene mostrato dove viene eseguita l'istanziazione. Mi sembra che le due liste variadiche debbano essere analizzate senza ambiguità perché la prima ha tipi e l'altra ha solo valori interi.

Se quanto sopra non è pensato per funzionare, penso che quanto segue non funzionerà neanche.

template <class Ret, class... Args, Ret (*func)(Args...)> 
class Foo {}; 

Penso che il modello Foo sia una cosa piuttosto utile da avere.

+2

Il modello 'Foo' sarebbe come dire' template ', l'ultimo parametro template in realtà non aggiunge nulla ed è quindi completamente unnessecary, dopotutto il tipo può essere espresso bene usando il parametri del template (ad esempio 'typedef Ret (* func) (Args ...)' all'interno di 'Foo') – Grizzly

+2

@Grizzly: l'ultimo parametro non fornisce un * tipo * (che potrebbe essere sostituito da typedef), sta fornendo un puntatore di funzione. Un puntatore a funzione che viene sostituito in fase di compilazione, consentendo in tal modo l'ottimizzazione procedurale incrociata come l'inlining. –

+0

@Sumant: hai ragione che sembra non ambiguo, tuttavia penso che lo Standard abbia semplicemente puntato alla semplicità specificando che un pacchetto di parametri era l'ultimo "parametro" possibile e che nulla poteva venire dopo. Questo rende più facile la corrispondenza. –

risposta

8

(Extra:. direttamente rispondere alla tua prima domanda, si può anche trasformare in un modello template<class...T, T... t> void func() {}-inside-a-template Questo non funziona in g ++ 4.6, ma lo fa in clang 3.0, quindi ci sono voluti me un po 'per trovarlo)

mettere un modello all'interno di un template:.

template<class ... T> 
struct func_types { 
    template <T ... t> 
    static void func_values() { 
     // This next line is just a demonstration, and 
     // would need to be changed for other types: 
     printf("%c %d\n", t...); 
    } 
}; 

int main() { 
    func_types<char, int> :: func_values<'A', 10>(); 
} 

è un modello-dentro-un-modello accettabile? Un'alternativa è usare le tuple con . . Penso che questo è fattibile, ma si potrebbe avere a rotolare la propria classe tupla (sembra che make_tuple non è un constexpr

Infine, si potrebbe essere in grado di implementare il modello Foo come segue:

template<typename Ret, typename ...Args> 
struct Foo { 
     template< Ret (*func)(Args...)> 
     struct Bar { 
       template<typename T...> 
       Bar(T&&... args) { 
         cout << "executing the function gives: " 
          << func(std::forward(args)...) << endl; 
       } 
     }; 
}; 

int main() { 
    Foo<size_t, const char*> :: Bar<strlen> test1("hi"); 
    Foo<int, const char*, const char*> :: Bar<strcmp> test2("compare","these"); 
} 

quest'ultimo codice è in ideone. per dimostrare, ho implementato un costruttore per inoltrare i args alla funzione che è il codice nel modello.

+1

Si noti che è male usare 'Args && ...', poiché l'inoltro perfetto è alimentato dalla deduzione argomento template. Si specificano i tipi di argomento esplicitamente tuttavia, in quanto tale è ridondante. – Xeo

+0

Ah sì, @Xeo. Dovrei sostituire 'func (args ...)' con 'func (std :: forward (args ...) 'altrimenti i rvalues ​​perdono il loro valore (supponendo che il nostro' func' abbia preso rvalues)? Questo ha senso per me. C'è qualche sottigliezza che mi manca? –

+0

.. oh, in realtà, penso di aver anche bisogno di rendere il costruttore stesso un modello, in modo da ottenere questa deduzione. –

2

Perché nessuno ha pensato che sarebbe stato la pena di avere questa funzione. la progettazione di variadic il modello era pensato per essere semplice e funzionante, altri potenzialmente avanzati e utili anche le misure non sono incluse.

Problemi correlati