2013-03-27 5 views
18

Supponiamo che io abbia una funzione template:Come passare una funzione template in un elenco di modelli argomenti

template<typename T> 
T produce_5_function() { return T(5); } 

Come posso passare tutto questo template ad un altro template?

Se produce_5_function era un funtore, non ci sarebbe nessun problema:

template<typename T> 
struct produce_5_functor { 
    T operator()() const { return T(5); } 
}; 
template<template<typename T>class F> 
struct client_template { 
    int operator()() const { return F<int>()(); } 
}; 
int five = client_template<produce_5_functor>()(); 

ma voglio essere in grado di fare questo con un modello di funzione grezzo:

template<??? F> 
struct client_template { 
    int operator()() const { return F<int>(); } 
}; 
int five = client_template<produce_5_function>()(); 

Ho il sospetto che la risposta è "non puoi farlo".

risposta

12

Sospetto che la risposta sia "non puoi farlo".

Sì, questo è il caso, non è possibile passare un modello di funzione come argomento modello. Da 14.3.3:

Un modello-argomento per un modello-parametro di modello è il nome di un modello di classe o di un modello di alias, espressa come id-espressione.

funzione

Il modello deve essere istanziati prima si passa all'altro modello. Una soluzione possibile è quella di passare un tipo di classe che contiene una statica produce_5_function in questo modo:

template<typename T> 
struct Workaround { 
    static T produce_5_functor() { return T(5); } 
}; 
template<template<typename>class F> 
struct client_template { 
    int operator()() const { return F<int>::produce_5_functor(); } 
}; 
int five = client_template<Workaround>()(); 

Uso dei modelli di alias, ho potuto ottenere un po 'più vicino:

template <typename T> 
T produce_5_functor() { return T(5); } 

template <typename R> 
using prod_func = R(); 

template<template<typename>class F> 
struct client_template { 
    int operator()(F<int> f) const { return f(); } 
}; 

int five = client_template<prod_func>()(produce_5_functor); 
+0

C'è una ragione fondamentale per cui i parametri di template non possono essere modelli di funzioni? È probabile che ciò venga affrontato in futuro? – Olumide

+0

@Olumide: Probabilmente perché è molto più complesso e facile da aggirare (vedi la risposta di mfontanini). Lo stesso vale per la specializzazione parziale, che viene utilizzata molto più degli argomenti del template template. –

2

Come avvolgere quella funzione?

template<typename T> 
struct produce_5_function_wrapper { 
    T operator()() const { return produce_5_function<T>(); } 
}; 

Quindi è possibile utilizzare il wrapper anziché la funzione:

int five = client_template<produce_5_function_wrapper>()(); 

Utilizzando la funzione di modello da solo non funziona, non c'è cosa come "funzioni template".

Problemi correlati