2016-06-29 14 views
0

Ich habe Funktionen Klassenmitglied wie folgt definiert, eine Spezifikation für eine von ihnen die Bereitstellung und Vermietung der Benutzer für andere ihre eigene Spezifikation liefern: Vorlage partielle Spezialisierung für mehrere Arten zwingende Memberfunktion

template <typename T> 
class Foo { 
    // specialization provided for integral types 
    template <typename Enable = T> 
    typename std::enable_if<std::is_integral<Enable>::value, size_t>::type 
     bar(const T& value); 

    // provide your own specialization for other types 
    template <typename Enable = T> 
    typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type 
     bar(const T& value); 
}; 

template <typename T> 
template <typename Enable> 
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type 
    Foo<T>::bar(const T& value) { 
    ... 
} 

Nun, ich würde gerne eine Spezialisierung für die Funktion bereitstellen, die für ganzzahlige Paartypen funktioniert. Ich habe eine Vorlage metafunction für integrale Paare Überprüfung wie folgt definiert:

template <typename T> 
struct is_integral_pair : std::false_type {}; 

template <typename T1, typename T2> 
struct is_integral_pair<std::pair<T1, T2>> { 
    static const bool value = 
     std::is_integral<T1>::value && std::is_integral<T2>::value; 
}; 

Ist es möglich für mich, meine eigene Spezialisierung zu schaffen, so dass es für alle ganzzahligen Paare funktioniert, vielleicht die Vorlage metafunction mit I oben definiert?

Antwort

0

Es ist ein bisschen ein künstliches Beispiel und etwas schwer zu verstehen, wie es ist. Mit einer grundlegenden Änderung ist es jedoch ziemlich einfach hinzuzufügen, was Sie benötigen. Zuerst ist es wichtig zu beachten, dass das, was Sie oben definieren, keine Teilspezialisierungen von bar sind (das wäre unmöglich, da Sie eine Funktion nicht teilweise spezialisieren können), sondern eher überladen. Als nächstes haben Sie ein künstliches System, bei dem Sie einen Enable Parameter haben, der nichts mit dem Funktionsparameter zu tun hat - ist das wirklich Ihre Absicht? Wenn Sie die Änderung vorgenommen haben, dass der Template-Parameter der Funktion vom gleichen Typ wie sein variabler Parameter ist, wird das Problem einfach - Sie fügen eine weitere Überladung für ganzzahlige Paare hinzu, wiederum mit SFINAE, um Ihnen zu helfen. Hier ist ein Beispiel Weg zu erreichen, was Sie brauchen:

#include <iostream> 

template <typename T> 
class Foo { 
public: 

    // specialization provided for integral types 
    template <typename Enable> 
    typename std::enable_if<std::is_integral<Enable>::value, size_t>::type 
     bar(const Enable& value); 

    // provide your own specialization for other types 
    template <typename Enable> 
    typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type 
     bar(const Enable& value); 

    // provide your own specialization for integral pairs 
    template <typename U, typename V> 
    typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type 
     bar(const std::pair<U,V>& value); 

}; 

template <typename T> 
template <typename Enable> 
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type 
    Foo<T>::bar(const Enable& value) 
{ 
    std::cout << "Integral" << std::endl; 
    return 0; 
} 

template <typename T> 
template <typename Enable> 
typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type 
    Foo<T>::bar(const Enable& value) 
{ 
    std::cout << "Non-Integral" << std::endl; 
    return 0; 
} 

template <typename T> 
template <typename U, typename V> 
typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type 
    Foo<T>::bar(const std::pair<U,V>& value) 
{ 
    std::cout << "Integral pair" << std::endl; 
    return 0; 
} 

int main() 
{ 
    Foo<int> foo; 

    foo.bar(1);    //output "Integral" 
    foo.bar(1.0);   //output "Non-Integral" 

    foo.bar(std::pair<float, int>(1.0, 1)); //output "Non-integral" 
    foo.bar(std::pair<long, int>(1, 1));  //output "Integral pair" 
    return 0; 
} 
Verwandte Themen