Dynamically indicate which method to use based on template type

Suppose I have a method that simplifies up to this

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
    }
} 

Now i use it as

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

Now val.secondin line A has 3 methods in it

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

I am currently using   val.second->getMethodA()with a template typeFirstType

In any case, I need to specify the use getMethodBif the type of the template SecondType and use getMethodCif the type of the templateThirdType

+4
source share
3 answers

The simplest solution is to replace the three member functions getMethodXwith one template function template<class T> T foo::getMethod(). Then create specializations for each type, if necessary.

, -:

template<class T>
struct helper {};

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

++ 17 constexpr if:

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 the absence of C ++ 17, I would probably go for something simple:

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>{});

In the context of your example:

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>{});
    }
}
+1
source

Source: https://habr.com/ru/post/1648895/


All Articles