2016-03-27 9 views
0

Ich habe nicht viel Erfahrung mit Vorlagen, aber ich versuche, Template-Spezialisierung basierend auf Aufzählungen mit einer Funktion, die verschiedene Klassen zurückgibt. Unten ist der Beispielcode (oder besser gesagt, was zu tun Ich versuche):C++ Template-Spezialisierung mit Klasse als Rückgabetyp und enum als Parameter

class Foo { 
    // member variables 
}; 
class Cat { 
    // member variables 
}; 

enum MyType{ A, B, C}; 

// Header file 
template<class T, MyType U> std_shared_ptr<T> process(); 

// cpp file/implementation 
template<> std_shared_ptr<Foo> process<Foo, A>() 
{ 
} 

template<> std_shared_ptr<Cat> process<Cat, C>(); 
{ 
} 

mir jemand in herauszufinden, helfen kann, was ich hier fehlt oder falsch? Ich habe versucht, es zu suchen und fand einige Lösungen für die Handhabung von Enum-Typen (Template specialization for enum), kann jedoch nicht herausfinden, wie man es mit einem Template-Rückgabetyp in einer Funktion zusammensetzt.

EDIT: Was ich hier tun möchte, ist Template-Spezialisierung basierend auf Aufzählungstyp als Argument für eine Funktion zu tun. Und die gleiche Funktion gibt auch eine Template-Klasse zurück. Die Funktion hat also hier zwei Templates: T (return param) und U (input param, das eine enum ist). Ist es möglich?

EDIT: Das obige Beispiel für das richtige Verhalten geändert.

+1

Scheint wie [ein XY-Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). –

+0

Ich verstehe nicht, was Sie erreichen sollen. Zum Beispiel, in Vorlage ... Prozess (U-Eingabe) - U ist ein Wert, kein Typ, also was bedeutet U-Eingabe? Vielleicht solltest du in Worten erklären, was du gerne machen würdest. –

+0

@Ami Tavory Weitere Details im EDIT-Bereich hinzugefügt. Ich bin nicht sehr vertraut mit Vorlagen, also habe ich vielleicht nicht die richtige Frage gestellt. – pree

Antwort

1

Sie können Vorlagenfunktionen nicht teilweise spezialisieren.

Der Wert, nicht der Typ eines Funktionsparameters kann den Typ des Rückgabewerts nicht ändern. Der Wert eines nicht typisierten Vorlagenparameters kann den Typ des Rückgabewerts ändern, der jedoch innerhalb der <> übergeben wird und die Kompilierzeit muss ermittelt werden, nicht innerhalb der () s.

Tags können helfen.

template<MyType X> 
using my_type_tag_t=std::integral_constant<MyType, X>; 
template<MyType X> 
constexpr my_type_tag_t<X> my_type_tag = {}; 

template<class T>struct tag_t{using type=T;}; 
template<class Tag>using type=typename Tag::type; 

template<MyType> 
struct my_type_map; 
template<> 
struct my_type_map<MyType::A>:tag<Foo>{}; 
template<> 
struct my_type_map<MyType::B>:tag<Cat>{}; 

dann:

template<MyType X> 
std::shared_ptr<type<my_type_map<X>>> 
process(my_type_tag_t<X>); 

wo Sie process(my_type_tag<A>) rufen Sie einen shared_ptr<Foo> aus ihm heraus zu bekommen.

Implementationen wie folgt aussehen:

template<> 
std::shared_ptr<Foo> 
process(my_type_tag_t<MyType::A>) { 
    // blah 
} 

noch unelegant, und wahrscheinlich Ihr Problem nicht lösen, aber es ist in der Nähe Ihrer beschriebenen Lösung.