I am trying to compile the following program.
#include <iostream>
#include <thread>
struct State
{
State (std::string message) : message (message)
{
}
template <class Function, class... Args>
void
spawn (Function&& function, Args&&... args)
{
std::thread t (&State::run <Function, Args...>, this, function, args...);
t . join ();
}
template <class Function, class... Args>
void
run (Function&& function, Args&&... args)
{
std::cout << this -> message << std::endl;
function (args...);
}
~State () = default;
std::string message;
};
void
print (std::string message)
{
std::cout << message << std::endl;
}
int main (int argc, char ** argv)
{
State state ("Hello, World!\n");
state.spawn (print, "Goodbye, World!\n");
return 0;
}
When I try to compile it using clang 6.0.1, I get the following output.
$ clang++ main.cpp
In file included from main.cpp:2:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:242:40: error:
no matching member function for call to '_M_invoke'
-> decltype(std::declval<_Invoker&>()._M_invoke(_Indices()))
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:127:8: note:
in instantiation of template class
'std::thread::_Invoker<std::tuple<void (State::*)(void
(&)(std::__cxx11::basic_string<char>), char const (&)[17]), State *,
void (*)(std::__cxx11::basic_string<char>), const char *> >'
requested here
__make_invoker(std::forward<_Callable>(__f),
^
main.cpp:14:15: note: in instantiation of function template specialization
'std::thread::thread<void (State::*)(void
(&)(std::__cxx11::basic_string<char>), char const (&)[17]), State *,
void (&)(std::__cxx11::basic_string<char>), char const (&)[17]>'
requested here
std::thread t (&State::run <Function, Args...>, thi...
^
main.cpp:41:8: note: in instantiation of function template specialization
'State::spawn<void (&)(std::__cxx11::basic_string<char>), char const
(&)[17]>' requested here
state.spawn (print, "Goodbye, World!\n");
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:231:4: note:
candidate template ignored: substitution failure [with _Ind = <0, 1,
2, 3>]: no matching function for call to '__invoke'
_M_invoke(_Index_tuple<_Ind...>)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:186:13: error:
type 'std::thread::_Invoker<std::tuple<void (State::*)(void
(&)(std::__cxx11::basic_string<char>), char const (&)[17]), State *,
void (*)(std::__cxx11::basic_string<char>), const char *> >' does not
provide a call operator
_M_run() { _M_func(); }
^~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:182:2: note:
in instantiation of member function
'std::thread::_State_impl<std::thread::_Invoker<std::tuple<void
(State::*)(void (&)(std::__cxx11::basic_string<char>), char const
(&)[17]), State *, void (*)(std::__cxx11::basic_string<char>), const
char *> > >::_M_run' requested here
_State_impl(_Callable&& __f) : _M_func(std::forward<_Callab...
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:197:24: note:
in instantiation of member function
'std::thread::_State_impl<std::thread::_Invoker<std::tuple<void
(State::*)(void (&)(std::__cxx11::basic_string<char>), char const
(&)[17]), State *, void (*)(std::__cxx11::basic_string<char>), const
char *> > >::_State_impl' requested here
return _State_ptr{new _Impl{std::forward<_Callable>(__f)}};
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../include/c++/8.2.0/thread:126:25: note:
in instantiation of function template specialization
'std::thread::_S_make_state<std::thread::_Invoker<std::tuple<void
(State::*)(void (&)(std::__cxx11::basic_string<char>), char const
(&)[17]), State *, void (*)(std::__cxx11::basic_string<char>), const
char *> > >' requested here
_M_start_thread(_S_make_state(
^
main.cpp:14:15: note: in instantiation of function template specialization
'std::thread::thread<void (State::*)(void
(&)(std::__cxx11::basic_string<char>), char const (&)[17]), State *,
void (&)(std::__cxx11::basic_string<char>), char const (&)[17]>'
requested here
std::thread t (&State::run <Function, Args...>, thi...
^
main.cpp:41:8: note: in instantiation of function template specialization
'State::spawn<void (&)(std::__cxx11::basic_string<char>), char const
(&)[17]>' requested here
state.spawn (print, "Goodbye, World!\n");
^
2 errors generated.
I can't tell what I am doing wrong. I can tell that the compiler doesn't seem to like the first argument that I am passing to the thread object, but I don't know why or how to fix it.
I've tried to change the function from a member function reference to a static member function reference (adding the struct pointer as an additional argument). This has no substantial effect on the output.
I've also tried compiling it with GCC, to see if it tells me anything interesting. It seems to have the same problem with the code that clang does, but the output is more verbose and equally unenlightening to me.
Why does my program not compile? What is this error message trying to tell me?