This question already has an answer here:
I am trying to understand the root cause of the compilation error that I get when the trying to compile the following:
#include <iostream>
#include <string>
#include <thread>
#include <type_traits>
using namespace std;
using namespace std::chrono;
void function(string& str) {
std::reverse(str.begin(), str.end());
cout << "In thread function after reverse: " << str << endl;
}
int main(int argc, char* argv[]) {
std::string string_main("I am not modified");
cout << "Before: " << string_main << endl;
thread t1(function, string_main);
t1.join();
cout << "After: " << string_main << endl;
return 0;
}
- I know that this should not be done and it would not even behave as expected.
-
I also know that a simple std::ref would make this code compile just fine.
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/thread:120:2: error: static_assert failed due to requirement '__is_invocable, allocator > &)>::type, typename decay, allocator > &>::type>::value' "std::thread arguments must be invocable after conversion to rvalues" static_assert( __is_invocable::type, ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tutorial3.cpp:34:10: note: in instantiation of function template specialization 'std::thread::thread, std::allocator > &), std::__cxx11::basic_string, std::allocator > &, void>' requested here thread t1(function, string_main); ^ In file included from tutorial3.cpp:6: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/thread:252:40: error: no matching member function for call to '_M_invoke' -> decltype(std::declval<_Invoker&>()._M_invoke(_Indices()))
The error that I get basically boils down to
static_assert failed due to requirement... std::thread arguments must be invocable after conversion to rvalues
According to the error it looks like that the thread is instantiated in the following manner:
tutorial3.cpp:34:10: note: in instantiation of function template specialization
'std::thread::thread<void (&)(std::__cxx11::basic_string<char...> &), std::__cxx11::basic_string<char... > &, void>' requested here
thread t1(function, string_main);
string_main
is taken as a reference to a string in the thread
constructor but somehow the following assert is failing:
__is_invocable<typename decay<void (&)(basic_string<char...> &)>::type, typename decay<basic_string<char...> &>::type>::value'
Is it failing because decay
is removing the reference to string_main
and __is_invocable
returns true only if the parameters match the function signature exactly?
I believe this is the right explanation even because the following assert fails:
static_assert( std::is_invocable<void(string&), std::string>::value );
Apparently std::is_invocable
does not allow a void(string&) to be called with a std::string
.
Aucun commentaire:
Enregistrer un commentaire