简体   繁体   中英

Cast unresolved template overloaded class member

I have a class with two overloaded members. One takes an integer, the other one is a template function taking one argument.

class MyClass
{
    public:
        void doSomething(int data){ std::cerr << data;}
        template <typename T> doSomething(T &&data){ std::cerr << data;}
};

I want to bind this function

MyClass myobject;
auto my_bind = std::bind(&MyClass::doSomething, &myobject, 2);
my_bind();

But this doesn't compile since the compiler cannot deduct which function to call.

error: no matching function for call to 'bind(unresolved overloaded function type, MyClass*, int)'

I understand that I have to cast the function.

auto my_bind2 = std::bind(static_cast<void (MyClass::*)(int)>(&MyClass::doSomething), &myobject, 2);

And now it compiles and works as expected.

But what if I want to bind it with any other parameter to call the template function? Is this even possible? I cannot find the syntax.

This doesn't work:

auto my_bind3 = std::bind(static_cast<void (MyClass::*)(std::string)>(&MyClass::doSomething), &myobject, std::string("Hello"));

I would like to avoid using lambdas. I simplified the code for MCVE but in the actual code I am supposed to use member pointers.

Thank you for the help

You should simply provide the address of a relevant instantiation of the member function-template :

auto my_bind3 = std::bind(&MyClass::doSomething<std::string&>, &myobject, std::string("Hello"));
                                 //Note the reference here ^^

The above works because std::bind copies its arguments, and since the doSomething member function template takes its argument by a forwarding reference , we need to take advantage of reference collapsing.

While something like the snippet below will "bind",

auto my_bind3 = std::bind(&MyClass::doSomething<std::string>, &myobject, std::string("Hello"));
                    //Note the absence of a reference here ^^

It is going to fail when you eventually call my_bind3() .

Demo


If you can use a lambda, use it, because perfect forwading will kick in.

auto my_bind4 = [&myobject](){ myobject.doSomething(std::string("\nHullo")); };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM