Reputation: 115
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
std::function<void()> f = std::bind(&Test::work, &test);
thread th(f);
th.join();
return 0;
}
As above code, I want to bind member function void work(void)
of a class (let's name it Test) , but occurs compiler error saying that can not determine which overrided function to use.
I can not change class Test since it belongs to a lib, how to achieve my goal? Thanks in advance!
Upvotes: 10
Views: 1597
Reputation: 134
Why don't skip std::bind
altogether and use a lambda?
auto fp = [&t]() { t.test()};
As a bonus, your executable size will be smaller and your compiler has much easier time to inline the code if appropriate.
Upvotes: 6
Reputation: 69882
When deducing the template arguments to bind, the compiler is not in a context that allows function overload resolution - to be simplistic about it, it hasn't got that far yet.
Having deduced that the first argument is indeed the name of a member function pointer, it finds that there are two functions of the same name but of different types.
At this stage, they're both equally valid candidates (from the point of template argument deduction), therefore it's ambiguous
A static cast disambiguates because we're pushing the compiler beyond the stage where it has to deduce a template type - we have taken on the responsibility to template type deduction ourselves - by specifying the type in the static_cast
.
So now all it has to do is overload resolution.
#include <functional>
#include <thread>
#include <iostream>
using namespace std;
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
// only overload resolution required here
auto fp = static_cast<int (Test::*)()>(&Test::work);
// type is now unambiguous and overload resolution is already done
std::function<void()> f = std::bind(fp, &test);
thread th(f);
th.join();
return 0;
}
Upvotes: 3
Reputation: 297
try this(member function ptr):
int main(){
Test test;
typedef int(Test:: *WKPtr)(void);
WKPtr p = &Test::work;
std::function<int()> f = std::bind(p, &test);
f();
return 0;
}
Upvotes: 1
Reputation: 55395
By casting it to the correct type:
std::function<void()> f = std::bind( static_cast<int (Test::*)()>(&Test::work), &test);
Upvotes: 5