5

Ich möchte folgendes schreiben:Was soll ich anstelle der Teilspezialisierung von Funktionsvorlagen tun?

template <typename S, typename T> void foo() { 
    /* code for the general case */ 
} 

template <typename T> void foo<MySType,T>() { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

oder in anderen Fällen, die folgenden:

template <typename S, typename T> void bar(const S& a, const T& b) { 
    /* code for the general case */ 
} 

template <typename T> void bar<MySType,T>(const MySType& a, const T& b) { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

C++ (11) wird mich das nicht tun lassen.

Jetzt lese ich this question and its answers; Nehmen wir an, ich kaufe die Erklärung, warum wir keine partielle Template-Spezialisierung haben (oder einfach davon ausgehen, dass ich in der Realität lebe und tatsächlich Code schreiben möchte). Nun, was tun Ich mache, statt?

Ich würde wirklich lieber nicht diese Funktionen in einer Klasse wickeln, es sei denn das ist absolut mein letzter Ausweg.

+0

ehrlich desto tauche ich in C++ 11 und C++ im Allgemeinen, je mehr ich denke, dass „Template-Spezialisierung“ ist eine schreckliche Qualifikation für das, was passiert ist, . Es gibt keine "Template-Spezialisierung" – user2485710

+0

@ user2485710: Tut mir leid, ich verstehe nicht ... können Sie das näher erläutern? Oder Link zu dem, wo Sie das länger diskutiert haben? – einpoklum

+1

Nicht nur die Template-Spezialisierung ist eine Sache, sondern auch eine Turing-Komplettmaschine. Es kann dich jedoch verrückt machen. – Potatoswatter

Antwort

3

Eine weitere Option ist eine Hilfsklasse Vorlage zu verwenden, wo Sie Teil Spezialisierung tun können, und verstecken es eine Wrapper-Funktion, die nicht selbst werden muss teilweise spezialisiert:

#include <iostream> 

template<typename S, typename T> 
struct foo_helper { 
    void foo() { 
     std::cout << "general func" << std::endl;   
    } 
}; 

struct MyType {}; 

template <typename T> 
struct foo_helper <MyType,T> { 
    void foo() { 
     std::cout << "partially specialized code - for any kind of T, but when S is MyType" << std::endl; 
    } 
}; 

template<typename S, typename T> 
void foo() { 
    foo_helper<S, T>().foo(); 
} 

int main() { 
    foo<int, int>(); 
    foo<int, double>(); 
    foo<MyType, long>(); 
} 

Dies ist Gültiges C++ 98/03.

+0

Kann ich die Verwendung der Hilfsstruktur irgendwie automatisieren/macroisieren? – einpoklum

5

Überlastung! Überladen ist in jeder Hinsicht der Spezialisierung überlegen. Ein Teil der Überladungsauflösung ist die Auswahl der am meisten spezialisierten Überladung. Erklären Sie einfach die "Spezialisierungen" als Überlastungen und es wird funktionieren, wenn eine Teilspezialisierung hätte.

Vermeiden Sie jedoch explizite Vorlagenargumente. Sie könnten stattdessen die Tag-Verteilung verwenden.

Da die Tags leer sind und als Wert übergeben werden, kann ihr Beitrag zum Funktionsaufruf-Overhead vom Compiler eliminiert werden.

+0

Das OP-Beispiel ist schlecht aufgebaut (fehlende Rückgabetypen usw.), bringt aber eine interessante Wendung. Hauptsächlich, wie überlädt du etwas, das * keine Parameter * hat? – WhozCraig

+0

@WhozCraig Siehe Update – Potatoswatter

+0

+1 Ich war im Begriff, ein Tag-Versand = P – WhozCraig

2

Sie könnten einen Helfer Struktur teilweise spezialisiert:

#include <iostream> 

namespace Detail { 
    template <typename S, typename T> 
    struct Foo { 
     static void apply() { 
      std::cout << "general case\n"; 
     } 
    }; 
    template <typename T> 
    struct Foo<int, T> { 
     static void apply() { 
      std::cout << "specialized code\n"; 
     } 
    }; 
} 

template <typename S, typename T> 
void foo() { 
    Detail::Foo<S, T>::apply(); 
} 

int main() 
{ 
    foo<double, double>(); 
    foo<int, double>(); 
    return 0; 
} 
+0

Kann das irgendwie irgendwie automatisiert werden, so dass ich nicht immer explizit in den Namespace, die Structs et cetera schreiben muss? – einpoklum