2016-07-23 5 views
4

Angenommen habe ich eine Methode, die nun auf dieseDynamisch, welche Methode auf einem Vorlagentyp basiert verwenden

template<typename t,typename u> 
std::shared_ptr<bar> MyClass::getFunct(std::string SomeStr) 
{ 
    ..... 
    std::map<std::string,std::shared_ptr<foo> > j; 
    .... 
    std::shared_ptr<u> collection(new u()); 
    for (auto val : j){ 
    val.second->getMethodA() //Will return object of type t <----LINE A 
    } 
} 

vereinfacht ich es als

getFunct<FirstType>("SomeString") 
getFunct<SecondType>("SomeString") 
getFunct<ThirdType>("SomeString") 

Jetzt val.second in Linie A bin mit hat 3 Methoden drin

val.second->getMethodA() //returns a type of FirstType 
val.second->getMethodB() //returns a type of SecondType 
val.second->getMethodC() //returns a type of ThirdType 

Momentan verwende ich val.second->getMethodA() mit Vorlagentyp FirstType

ist es für mich trotzdem angeben getMethodB zu verwenden, wenn und getMethodC Vorlagentyp SecondType ist zu verwenden, wenn Vorlagentyp ThirdType

+1

Das klingt wie das XY-Problem. Was ist das Designproblem, das Sie versuchen zu lösen? Binding-Funktionen zu Objekt ist möglich über 'std :: bind()' – lorro

+0

Lassen Sie mich das Problem beheben –

Antwort

1

Die einfachste Lösung ist, die drei getMethodX Member-Funktionen ersetzen eine einzige Vorlagenfunktion template<class T> T foo::getMethod(). Erstellen Sie dann bei Bedarf für jeden Typ Spezialisierungen.

Aber wenn das nicht geeignet für das Design ist, dann können Sie eine Wrapper-Funktion verwenden, anstatt:

template<class T> 
struct helper {}; 

template<> 
struct helper<FirstType> { 
    static FirstType getMethod(foo& f) { 
     return f.getMethodA(); 
    } 
}; 
// repeat specializations for other member functions 
+0

Yeah sieht aus, als ob ich etwas wie das implementieren muss –

1

Mit C++ 17 Sie können constexpr if verwenden:

template<typename T> 
decltype(auto) foo(Bar& bar){ 
    if constexpr(std::is_same_v<T,FirstType>){ 
     return bar.getMethodA(); 
    } 
    if constexpr(std::is_same_v<T,SecondType>){ 
     return bar.getMethodB(); 
    } 
    if constexpr(std::is_same_v<T,ThirdType>){ 
     return bar.getMethodC(); 
    } 
} 
1

In Abwesenheit von C++ 17 Ich würde wahrscheinlich für etwas einfaches wie folgt gehen:

template <typename T> struct type {}; 

struct select 
{ 
    bar &b; 
    decltype(auto) operator()(type<FirstType>) const { return b.getMethodA(); } 
    decltype(auto) operator()(type<SecondType>) const { return b.getMethodB(); } 
    decltype(auto) operator()(type<ThirdType>) const { return b.getMethodC(); } 
}; 
select{*val.second}(type<T>{}); 

Im Zusammenhang mit Ihr Beispiel:

template <typename T> struct type {}; 

template<typename t,typename u> 
std::shared_ptr<bar> MyClass::getFunct(std::string SomeStr) 
{ 
    ..... 
    std::map<std::string,std::shared_ptr<foo> > j; 
    .... 
    for (auto val : j) { 
     struct select { 
      bar &b; 
      decltype(auto) operator()(type<FirstType>) const { return b.getMethodA(); } 
      decltype(auto) operator()(type<SecondType>) const { return b.getMethodB(); } 
      decltype(auto) operator()(type<ThirdType>) const { return b.getMethodC(); } 
     }; 
     select{*val.second}(type<t>{}); 
    } 
} 
Verwandte Themen