I have an error that I do not understand when I try to make
part of a library I am writing. Can someone please point me in the right direction?
I have a member function that creates two std::threads
that both use std::promise
and std::ref
. I am compiling with CMake and linking the threads library without issue.
Below is a section of my .h file where you can see the functions I want to send my threads to:
object.h
void ThreadFunction1(std::promise<bool> &prom);
void ThreadFunction2(std::promise<bool> &prom, const std::vector<std::string> &things);
Now here is the snippet of code that is causing my build to fail:
object.cpp
bool Object::work(const std::vector<std::string> &things)
{
// starting point for work mode threads
// thread 1
std::promise<bool> prom1;
std::future<bool> fut1 = prom1.get_future();
std::thread(&Object::ThreadFunction1, std::ref(prom1), this).detach(); // <<-- this line right here
// thread 2
std::promise<bool> prom2;
std::future<bool> fut2 = prom2.get_future();
std::thread(&Object::ThreadFunction2, std::ref(prom2), std::ref(things), this).detach(); // <<-- and this line
if (fut1.get() && fut2.get())
{
return true;
}
else
{
printf("ERROR: work() threads have failed.\n");
return false;
}
} // end work
The lines that cause my build to fail are the std::thread(...).detach()
lines.
Errors:
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (Object::*)(), std::reference_wrapper<std::promise<bool> >, Object> >::_M_invoke(std::thread::_Invoker<std::tuple<void (Object::*)(), std::reference_wrapper<std::promise<bool> >, Object> >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:258:4: error: no matching function for call to ‘std::tuple<void (Object::*)(), std::reference_wrapper<std::promise<bool> >, Object>::tuple(<brace-enclosed initializer list>)’
} };
^
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (Object::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> >, Object*> >, std::__tuple_element_t<1, std::tuple<void (Object::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> >, Object*> >, std::__tuple_element_t<2, std::tuple<void (Object::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> >, Object*> >)’-> decltype(std::__invoke(_S_declval<_Ind>()...))
And then I get a lot of other errors that are similar. I can post them if needed, but they all start with error: no matching function call for ...
I have been looking at this code for days, googling everything I could think of. I looked at What is std::invoke in C++?, I read this reference page, Use member function for std::thread with std::ref(*this) fails to compile, C++11 std::thread giving error: no matching function to call std::thread::thread, and a number of other SO and blog posts about threads.
What I've Tried
I think the issue is std::ref()
, but I don't know why. When I test my code with std::thread(&Object::function, this).detach()
my code builds fine. I also tested std::ref()
in a trivial scrap .cpp file that was not a class/object, it built and ran fine as well. Edit: here us my trivial code test:
using namespace std;
int main(int argc, char *argv[])
{
promise<bool> promise1;
future<bool> future1 = promise1.get_future();
std::thread (ThreadFunction1, ref(promise1)).detach();
promise<bool> promise2;
future<bool> future2 = promise2.get_future();
std::thread thread2(ThreadFunction2, ref(promise2));
thread2.detach();
cout << "In Main..." << endl;
if (future1.get() && future2.get())
{
cout << "Everything was a-okay" << endl;
}
else
{
cout << "Whoops, there was an error..." << endl;
}
} // end main
void ThreadFunction1(promise<bool> &prom )
{
cout << "Thread " << this_thread::get_id() << " working in ThreadFunction1!" << endl;
sleep(10);
cout << "Thread " << this_thread::get_id() << " finished sleeping in Function1" << endl;
prom.set_value_at_thread_exit(true);
}
void ThreadFunction2(promise<bool> &prom )
{
cout << "Thread " << this_thread::get_id() << " working in ThreadFunction2!" << endl;
sleep(2);
cout << "Thread " << this_thread::get_id() << " finished sleeping in Function2" << endl;
prom.set_value_at_thread_exit(true);
}
I tried std::thread(&Object::ThreadFunction1, &prom1, this).detach();
(after looking here) but I received the same errors as above. I tried swapping this
and std::ref()
like this: std::thread(&Object::ThreadFunction1, this, std::ref(prom1)).detach();
but that didn't fix anything either.
What exactly is going on? What am I missing?
Aucun commentaire:
Enregistrer un commentaire