4

Consider the following code:

class A
{
    ....
    shared_ptr<std::thread> mThread;
    void Step();
    void LaunchTrhead();
}

void A::LaunchThread()
{
    ...
    mThread=make_shared<std::thread>(Step); // This line gives an error
    ...
}

void A::Step()
{
    ...
}

I'm trying to initialise the shared pointer mThread so that it calls the function Step. However, the compiler gives me the error "invalid initialization of reference of type ... from expression of type 'unresolved overloaded function type'". Obviously I'm doing something stupid, but I can't put my finger on it. Can anybody help? Thanks in advance!

DrD
  • 419
  • 4
  • 14

3 Answers3

8

Step() is a non-static member function, so it has an implicit first parameter of type A*. You need to bind the current instance of A when invoking it.

mThread = std::make_shared<std::thread>(std::bind(&A::Step, this));

You can also use a lambda instead of bind

mThread = std::make_shared<std::thread>([this]{ Step(); });

As @Casey points out in the comments, std::thread's constructor has special treatment for pointer to member functions, and will assume the first following argument is a pointer or reference to the instance on which to call the member function. This means you can avoid bind and directly pass this as the second argument.

mThread = std::make_shared<std::thread>(&A::Step, this);
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • On the spot! The compiler was telling me ("unresolved function"), but I just couldn't see it, I was completely blinded (I should go home...). Also, in line with what you pointed out, I could declare *Test* static. But your solution is more practical in my case, because it avoids having to pass a pointer to the owner object. Thank you! – DrD Feb 14 '14 at 14:30
  • 1
    You can pass a pointer-to-member and pointer-to-object directly to the `std::thread` constructor (and `std::bind`, and `std::async`): `mThread = std::make_shared(&A::Step, this);` – Casey Feb 14 '14 at 16:12
  • Thanks a lot Casey, that's an even more elegant solution :) – DrD Feb 17 '14 at 13:31
  • @Casey How do we pass functional with 1 or more arguments? Suppose the function step had a "function pointer" as an argument then what would be the syntax? – Vatsal Aggarwal May 03 '19 at 12:41
  • @VatsalAggarwal Pass the additional arguments to `thread`'s constructor (or `make_shared` in the example above) – Praetorian May 03 '19 at 14:12
1

Try (use labda instead of the free function):

mThread=make_shared<std::thread>([this](){ Step(); }); 

The way it is, you're not passing a reference to this to the constructor inspite of it being a member function.

This solution uses a lambda to create a function-object that takes no parameters but has a reference to this.

If you want to use the global function do this instead, and move void Step() to before it's usage:

mThread=make_shared<std::thread>(::Step()); 

the :: removes the ambiguity over the scope of the function.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
nishantjr
  • 1,788
  • 1
  • 15
  • 39
  • ::Step() doesn;t work, sorry. The lambda solution does. Thanks! – DrD Feb 14 '14 at 14:31
  • Step() is a member function, only that I forgot to include A:: in its declaration. Now it's edited. My apologies. – DrD Feb 14 '14 at 16:18
0

You should use shared_from_this() replace this

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339