0

I would like to spawn a thread or a future calling this function:

std::string myClass::myFunction() const noexcept

I first tried spawning them both like this:

thread t0(myFunction); auto f1 = async(myFunction);

I would then get this error:

no instance of constructor "std::thread::thread" matches the argument list. argument types are: (std::string () const)

I then read online that since it is const I would need to call it by reference but all methods online have not worked, I am unsure if the problem is because the function is const or not. What I have tried:

thread t0(&myClass::myFunction); auto f1 = async(&myClass::myFunction);

and

thread t0(&myFunction); auto f1 = async(&myFunction);

After this I would have two new errors that I cannot find a solution to:

std::invoke: no matching overloaded function found.

and

Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'

I think this is due to my lack of understand on how threads and futures work but I am struggling to find literature that gives me any relation to this. Basically I don't really understand what rule I am breaking, if there is a fundamental flaw in my approach any direction or tips would be nice. Thank you for your time.

2 Answers2

0
std::string myClass::myFunction() const noexcept

This is not a function. This is a class method. There is a fundamental different between the two.

You cannot simply write

myFunction();

Somewhere in your code, other than in another method of the same class, which uses this to invoke a different method for the same instance of the class. Anywhere outside a method of the same class, myFunction(); won't compile, and your compilation error is the same exact reason. The first parameter to std::thread's constructor is a function, not a class method. It can be a class method, which I'll get to shortly. But your first error is confusion between the concept of a function and a class method, that you need to understand.

You could make myFunction() a static class function, which then works just like any, ordinary, function, and then feed it to std::thread as usual. Another option is to construct std::thread using a wrapper function that passes whichever class whose method you wish to invoke to the wrapper function, and the wrapper function uses it. The "whichever class" could be this:

void invoke_func(const myClass *ptr)
{
    ptr->myFunction();
}

// ...

std::thread new_thread{ this };

Another, a more modern approach that can be used to invoke a class method is to pass an additional parameter, a pointer to an instance of the class whose method you wish to invoke:

std::thread new_thread{ &myClass::myFunction, this };

The myFunction() method does not take any parameters here as arguments, but when the first parameter to std::thread's constructor is a class method, and not a function, the first parameter is taken to be a pointer to an instance of the class whose method gets invoked, with the remaining parameters getting forwarded as usual.

But you will need to figure out, on your own, which class's instance you are trying to invoke, whether this, or some other instance of your class.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

Although you can often write foo() inside a class to invoke this->foo(), as a shortcut, this is not the case when you're outright "naming" the member function, and that's what you're doing here as you are actually passing a member function pointer to std::thread.

It can work, you just need to supply the object pointer too:

std::thread t0(myFunction, this);

You could pass a pointer to a different myClass instead, if you liked!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055