2

I have a class with a template method and would like to store its specializations in a container. My question is whether it's valid to cast the specialized template method pointer to a non-template method pointer of the same class that shares the same signature. Consider:

#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;

struct S {
    using Method = void(S::*)();

    template <typename T>
    void method1() {
        cout << "method1(): " << T() << endl;
    }

    template <typename T, typename U>
    void method2() { 
        cout << "method2(): " << T() << ", " << U() << endl;
    }

    void call(string name)
    {
        auto method_pair = methods.find(name);
        if (method_pair == methods.end()) {
            cout << name << " not found" << endl;
            return;
        }

        Method& method = method_pair->second;
        (this->*method)();
    }

    unordered_map<string, Method> methods;
};

int main()
{
    S s;

    s.methods["method_int"] = &S::method1<int>;
    s.methods["method_bool"] = &S::method1<bool>;
    s.methods["method_int_int"] = &S::method2<int, int>;
    s.methods["method_bool_int"] = &S::method2<bool, int>;

    cout << boolalpha;
    s.call("method_int");
    s.call("method_bool");
    s.call("method_int_int");
    s.call("method_bool_int");
    s.call("nonexistant");

    return 0;
}

Output:

method1(): 0
method1(): false
method2(): 0, 0
method2(): false, 0
nonexistant not found

The above code compiles and runs just fine with no warnings on my setup. I'm pretty new to C++ member function pointers and I've read that casting them can be dangerous so that's why I'm asking.

Thanks in advance.

2
  • I can't see any cast in your code! Commented Sep 21, 2019 at 4:10
  • @AKL I thought &S::method1<int> would implicitly cast to Method, no? Sorry if not lmao. Commented Sep 21, 2019 at 4:23

1 Answer 1

2

After you instantiate a template method with distinct types it gets all the properties of a regular method: it becomes a distinct function with an address, name (that includes the types you used for instantiation), etc. So your approach is valid.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.