2015-05-11 8 views
13
template <unsigned int N> class myclass 
{ 
public: 
    template <typename... Args> void mymethod(Args... args) 
    { 
     // Do interesting stuff 
    } 
}; 

Ich möchte mymethod nur mit genau N doubles aufgerufen werden. Ist das möglich? Das heißt, sagen, dass ich habe:Eine variadische Template-Methode, um eine gegebene Anzahl von Doubles zu akzeptieren?

myclass <3> x; 
x.mymethod(3., 4., 5.); // This works 
x.mymethod('q', 1., 7.); // This doesn't work 
x.mymethod(1., 2.); // This doesn't work 

Wie kann ich das tun?

Antwort

17

Für die Anzahl der Argumente Constraint Sie leicht, wenn sizeof...(Args) == N überprüfen können, aber zu überprüfen, ob alle Argumente Doppelzimmer Sie einen rekursiven Typ Merkmal aufbauen müssen, die std::is_same für jedes der Argumente überprüft.

template<typename...> 
struct are_same : std::true_type 
{}; 

template<typename T> 
struct are_same<T> : std::true_type 
{}; 

template<typename T, typename U, typename... Types> 
struct are_same<T, U, Types...> : 
    std::integral_constant<bool, (std::is_same<T, U>::value && are_same<T, Types...>::value)> 
{}; 

Hinweis are_same wird zuerst erklärt und dann spezialisiert.

Dann implementieren Sie einfach die Einschränkung in Ihrer Methode Rückgabetyp mit std::enable_if unter Ausnutzung von SFINAE.

template <unsigned int N> class myclass 
{ 
public: 
    template <typename... Args> 
    typename std::enable_if<(are_same<double, Args...>::value && sizeof...(Args) == N), void>::type 
    /* void */ mymethod(Args... args) 
    { 
     // Do interesting stuff 
    } 
}; 
1

können versuchen, so etwas wie folgt vor:

#include <type_traits> 

template<class T, class...> 
struct all_same : std::true_type 
{}; 

template<class T, class U, class... TT> 
struct all_same<T, U, TT...> 
    : std::integral_constant<bool, std::is_same<T,U>{} && all_same<T, TT...>{}> 
{}; 


template <unsigned int N> class myclass 
{ 
    public: 
    template <typename... Args> 
    typename std::enable_if<sizeof...(Args) == N, void >::type mymethod(Args... args) 
    { 
     static_assert(all_same<double, Args...>{}, 
         "Not all args as Double"); 
    } 
}; 

<Demo>

+0

schließen aber die Nutzung von 'enable_if' ist etwas gebrochen und die Ergebnisse in UB hier (pro die Warnung in der Demo); Sie sollten es beim Erfolg "void" geben lassen. –

Verwandte Themen