2012-06-16 17 views
6

Considerare:specializzazione parziale di un modello

template <typename Function, typename ...Args> 
auto wrapper(Function&& f, Args&&... args) -> decltype(f(args...)) { 
//... 
} 

Esiste un modo di specializzarsi in parte il modello di cui sopra per tutti i casi in cui decltype(f(args...)) è un puntatore?

EDIT:
penso che può essere fatto con una classe di supporto modello che prende decltype(f(args...)) come argomento di un template, e specializzarsi la classe helper. Se conosci soluzioni migliori fammi sapere.

risposta

3

soluzione Uno SFINAE-based:

#include <type_traits> 

template< 
    typename Functor 
    , typename... Args 
    , typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...)) 
    , typename std::enable_if< 
     std::is_pointer<Result>::value 
     , int 
    >::type = 0 
> 
Result wrapper(Functor&& functor, Args&&... args) 
{ /* ... */ } 

template< 
    typename Functor 
    , typename... Args 
    , typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...)) 
    , typename std::enable_if< 
     !std::is_pointer<Result>::value 
     , int 
    >::type = 0 
> 
Result wrapper(Functor&& functor, Args&&... args) 
{ /* ... */ } 

È possibile adattare il test (qui, std::is_pointer<Result>) per le vostre esigenze.

1

Come si vede il tipo restituito non è un argomento modello o parte degli argomenti, quindi non è possibile sovraccaricare né specializzarsi. L'invio di un aiuto è la tua migliore opzione.

#include <type_traits> 

template<typename Func, typename... Args> 
void func_impl(Func&& f, Args&&... args, std::true_type) 
-> decltype(func_impl(std::forward<Args>(args)...)) 
{ } 

template<typename Func, typename... Args> 
void func_impl(Func&& f, Args&&... args, std::false_type) 
-> decltype(func_impl(std::forward<Args>(args)...)) 
{ } 

template<typename Func, typename... Args> 
auto func(Func&& f, Args&&... args) 
    -> decltype(func_impl(std::forward<Func>(f), std::forward<Args>(args)...)) 
{ return func_impl(std::forward<Func>(f), std::forward<Args>(args)..., 
        std::is_pointer<decltype(f(std::forward<Args>(args)...))>::type); } 

sembra un po 'strano per me a prendere la funzione di riferimento rvalue e anche se si omette anche l'inoltro nel tuo esempio originale.

Un'altra possibile soluzione potrebbe essere un argomento predefinito di modello e sovraccarico su quello. Ma questo non funzionerebbe bene con la lista degli argomenti.

Problemi correlati