2016-05-06 12 views
4

Ich habe eine Klasse wie folgt aus:reduzieren Templat-Klasse Argumente in C++

template <unsigned int A, unsigned int B> 
class Foo { ... }; 

Foo eine Methode namens bar() benötigt, aber ich brauche diese zu spezialisieren. Für einen Fall, wenn A == B, möchte ich, dass es eine Sache macht und sonst etwas anderes. Kann ich das tun, ohne eine if-Anweisung in die Funktion zu schreiben? Wie:

Foo<A, A>::bar() { ... } and Foo<A, B>::bar() { ... } 
+0

Spezialisierte Klassenspezialisierung hilft Ihnen nicht? – SergeyA

+0

Tag-Dispatching könnte auch helfen. – Jarod42

Antwort

5

können Sie teilweise Ihre Klasse spezialisieren:

#include<cassert> 

template<typename A, typename B> 
struct S { 
    void f(int i) { assert(i == 42); } 
}; 

template<typename A> 
struct S<A, A> { 
    void f(int i) { assert(i == 0); } 
}; 

int main() { 
    S<int, double> s1; 
    S<int, int> s2; 
    s1.f(42); 
    s2.f(0); 
} 
+0

Ich wusste nicht, dass ich das tun könnte. Vielen Dank! –

3

Eine weitere Lösung für partielle Spezialisierung ist enable_if. Ich habe angenommen, Sie haben Integer-Template-Parameter, aber wenn Sie Typen haben, können Sie verwenden.

Diese Antwort basierend auf Lösungen von hier: std::enable_if to conditionally compile a member function

http://coliru.stacked-crooked.com/a/692fbfff1b9d84e8

#include <iostream> 
#include <string> 

template <unsigned int A, unsigned int B> 
class Foo { 
    public: 

     template<unsigned int TA=A, unsigned int TB=B> 
     typename std::enable_if< TA == TB >::type 
     bar() { 
     std::cout << "equal version = " << A << " " << B << "\n"; 
     } 

     template<unsigned int TA=A, unsigned int TB=B> 
     typename std::enable_if< TA != TB >::type 
     bar() { 
     std::cout << "NON equal version = " << A << " " << B << "\n"; 
     } 
}; 

int main() 
{ 
    Foo<1, 1> f1; 
    f1.bar(); 

    Foo<1, 2> f2; 
    f2.bar();  
    return 0; 
} 

Ausgänge:

equal version = 1 1 
NON equal version = 1 2 

Beispiel für Template-Parameter getippt:

http://coliru.stacked-crooked.com/a/05d6a93480e870aa

#include <iostream> 
#include <string> 

template <typename A, typename B> 
class Foo { 
    public: 

     template<typename TA=A, typename TB=B> 
     typename std::enable_if<std::is_same<TA, TB>::value>::type 
     bar() { 
     std::cout << "equal version" << "\n"; 
     } 

     template<typename TA=A, typename TB=B> 
     typename std::enable_if<!std::is_same<TA, TB>::value>::type 
     bar() { 

     // This will cause compilation error if this bar() overload is to be instantiated 
     // but since it is not there is no compilation error 
     typename TA::non_exists ii = 0; 
     std::cout << "NON equal version" << "\n"; 
     } 
}; 
int main() 
{ 
    Foo<int, int> f1; 
    f1.bar(); 

    //Foo<int, float> f2; 
    //f2.bar();  
    return 0; 
} 
+0

Wenn ich nur die gleiche Version habe, dann wird nur das erklärt? –

+0

@PeterLenkefi Nur verwendete Funktionen sollten vom Compiler instanziiert werden – marcinj