I am trying to use std::async. I have written this code
template<transport_type tt>
void stop_update_distances(const std::vector<stop>& stops, stop& from, const general_s& s, const osrm_machine& machine){
//...not important code...
}
void tt_map::update_distances(pqxx::connection& conn, const general_s& s,
const osrm_machine& walk_machine, const osrm_machine& car_machine){
std::vector<std::future<void>> futures;
futures.reserve(stops.size());
for(stop& from : stops){
auto res = std::async(std::launch::async, stop_update_distances<CAR>, stops, from, s, car_machine);
futures.push_back(res);
}
}
but g++8 returned me this error
src/lib/tt_map.cpp: In member function ‘void kp::mp::tt_map::update_distances(pqxx::connection&, const kp::general_s&, const kp::osrm_machine&, const kp::osrm_machine&)’:
src/lib/tt_map.cpp:383:108: error: no matching function for call to ‘async(std::launch, <unresolved overloaded function type>, std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&)’
auto res = std::async(std::launch::async, stop_update_distances<CAR>, stops, from, s, car_machine);
^
In file included from src/lib/tt_map.cpp:11:
/usr/include/c++/8/future:1712:5: note: candidate: ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)’
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^~~~~
/usr/include/c++/8/future:1712:5: note: template argument deduction/substitution failed:
/usr/include/c++/8/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = void (&)(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&); _Args = {std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&}]’:
src/lib/tt_map.cpp:383:108: required from here
/usr/include/c++/8/future:1712:5: error: no type named ‘type’ in ‘class std::result_of<void (*(std::vector<kp::mp::stop>, kp::mp::stop, kp::general_s, kp::osrm_machine))(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&)>’
/usr/include/c++/8/future:1745:5: note: candidate: ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...)’
async(_Fn&& __fn, _Args&&... __args)
^~~~~
/usr/include/c++/8/future:1745:5: note: template argument deduction/substitution failed:
/usr/include/c++/8/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {void (&)(const std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&), std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&}]’:
src/lib/tt_map.cpp:383:108: required from here
/usr/include/c++/8/future:1745:5: error: no type named ‘type’ in ‘class std::result_of<std::launch(void (*)(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&), std::vector<kp::mp::stop>, kp::mp::stop, kp::general_s, kp::osrm_machine)>’
which I don't really understand.
I have followed the example in cppreference.com. Even though it doesn't work.
Thank you for any hint, what is wrong.
std::thread and similar classes by default make copies of their arguments, and pass them along to the thread function by value. This is probably not what you want here. The specific cause of the compiler error is that stop_update_distances takes stop& from parameter by non-const reference, and a temporary copy cannot be passed there.
It's hard to tell without knowing how stop_update_distances is expected to use its parameters, but my guess is, you probably want to pass them along by reference. You do this by wrapping them in std::ref or std::cref as needed. Something like this:
auto res = std::async(
std::launch::async,
stop_update_distances<CAR>,
std::cref(stops),
std::ref(from),
std::cref(s),
std::cref(car_machine));
Be careful with lifetime and access synchronization issued - you are now sharing objects between threads.
Related
Here's a watered down example of the code I'm try to compile:
#include <iostream>
#include <functional>
template <class F>
auto foo(F&& fun)
{
return [callback = std::forward<F>(fun)](auto&&... args) {
std::invoke(callback, std::forward<decltype(args)>(args)...);
};
}
int main()
{
std::string cur("running"), target("ok");
foo([s1 = cur, s2 = target](std::string const& arg) /*mutable*/ {
if (s1 == arg)
{
std::cout << s1 << std::endl;
}
})("not ok");
return 0;
}
put simply I have a function foo that accepts callables, and is supposed to build a new callable from them. For the sake of the example, above I'm just invoking the fun argument but in the real case there are some decorations done to the callable and the result is placed into a data structure that invokes such "actions" under some conditions.
This example compiles and works just fine. The problem manifests when trying to pass mutable lambdas to foo. When I uncomment the mutable keyword above, I get this compilation error:
main.cpp: In instantiation of 'foo<main()::<lambda(const string&)> >(main()::<lambda(const string&)>&&)::<lambda(auto:1&& ...)> [with auto:1 = {const char (&)[7]}]':
main.cpp:21:7: required from here
main.cpp:8:20: error: no matching function for call to 'invoke(const main()::<lambda(const string&)>&, const char [7])'
8 | std::invoke(callback, std::forward<decltype(args)>(args)...);
| ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:2:
/usr/local/include/c++/11.2.0/functional:94:5: note: candidate: 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...)'
94 | invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~
/usr/local/include/c++/11.2.0/functional:94:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c++/11.2.0/bits/move.h:57,
from /usr/local/include/c++/11.2.0/bits/nested_exception.h:40,
from /usr/local/include/c++/11.2.0/exception:148,
from /usr/local/include/c++/11.2.0/ios:39,
from /usr/local/include/c++/11.2.0/ostream:38,
from /usr/local/include/c++/11.2.0/iostream:39,
from main.cpp:1:
/usr/local/include/c++/11.2.0/type_traits: In substitution of 'template<class _Fn, class ... _Args> using invoke_result_t = typename std::invoke_result::type [with _Fn = const main()::<lambda(const string&)>&; _Args = {const char (&)[7]}]':
/usr/local/include/c++/11.2.0/functional:94:5: required by substitution of 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...) [with _Callable = const main()::<lambda(const string&)>&; _Args = {const char (&)[7]}]'
main.cpp:8:20: required from 'foo<main()::<lambda(const string&)> >(main()::<lambda(const string&)>&&)::<lambda(auto:1&& ...)> [with auto:1 = {const char (&)[7]}]'
main.cpp:21:7: required from here
/usr/local/include/c++/11.2.0/type_traits:2933:11: error: no type named 'type' in 'struct std::invoke_result<const main()::<lambda(const string&)>&, const char (&)[7]>'
2933 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
| ^~~~~~~~~~~~~~~
Any idea why is that? Can my foo accept mutable lambdas as well?
Just add mutable to the lambda inside the foo:
template <class F>
auto foo(F&& fun)
{
return [callback = std::forward<F>(fun)](auto&&... args) mutable {
//^^^
std::invoke(callback, std::forward<decltype(args)>(args)...);
};
}
I'm facing a thread problem.
I tried to execute function inside a thread from Chronometer class including a while loop:
Here is the part code:
for(int i = 0; i<car_data.size();i++)
{
if(car_data[i]->checkArea(frame, pt1_zone, pt2_zone))
{
std::thread(&Chronometer::start_chrono, car_crono[i], std::ref(chrono));
cv::rectangle(frame, car_data[i]->pt1, car_data[i]->pt2, cv::Scalar(255,0,0), 1, cv::LINE_8,0);
//cv::putText(frame, "Parked", car_data[i]->pt1, cv::FONT_HERSHEY_DUPLEX, 0.9, cv::Scalar( 50, 255, 50 ));
//occupancy_state = place.occupancyTrue();
//place_1.occupancy = true;
The type of car_crono and chrono
std::vector<Chronometer*> car_crono;
Chronometer chrono;
Here is my class Chronometer:
class Chronometer
{
private:
static int hour, min, sec;
//std::stringstream ss;
//Chronometer chrono;
public:
Chronometer();
static Chronometer& start_chrono(Chronometer& chrono);
static Chronometer& finish_chrono(Chronometer& chrono);
friend std::ostream& operator<<(std::ostream& flux, Chronometer t);
Chronometer& operator=(const Chronometer& other);
~Chronometer();
};
For the thread I tried several kind of parameters. The last one:
std::thread(&Chronometer::start_chrono, car_crono[i], std::ref(chrono));
I guessed a ref was necessary but doesn't change.
Here is the full error
/usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >’:
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Chronometer& (*)(Chronometer&); _Args = {Chronometer*&, std::reference_wrapper<Chronometer>}]’
recognizer_rtsp.cxx:348:76: required from here
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >::_M_invoke(std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> >]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
/usr/include/c++/7/thread:231:4: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2}]’:
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Chronometer& (*)(Chronometer&); _Args = {Chronometer*&, std::reference_wrapper<Chronometer>}]’
recognizer_rtsp.cxx:348:76: required from here
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >, std::__tuple_element_t<1, std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >, std::__tuple_element_t<2, std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >)’
-> decltype(std::__invoke(_S_declval<_Ind>()...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/tuple:41:0,
from /usr/include/c++/7/bits/stl_map.h:63,
from /usr/include/c++/7/map:61,
from ../alpr_utils.h:7,
from recognizer_rtsp.cxx:34:
/usr/include/c++/7/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/include/c++/7/bits/invoke.h:89:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = Chronometer& (*)(Chronometer&); _Args = {Chronometer*, std::reference_wrapper<Chronometer>}]’:
/usr/include/c++/7/thread:233:29: required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2}]’
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> > >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Chronometer& (*)(Chronometer&); _Args = {Chronometer*&, std::reference_wrapper<Chronometer>}]’
recognizer_rtsp.cxx:348:76: required from here
/usr/include/c++/7/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<Chronometer& (*)(Chronometer&), Chronometer*, std::reference_wrapper<Chronometer> >’
What kind of parameter should I pass through the thread ?
I went to several links to find a solution but nothing could solve my problem:
std::thread pass by reference calls copy constructor
No matching function to invoke, using std::thread
...
Chronometer::start_chrono is a static function, so it's not bound to any object, i.e doesn't need an object to called upon.
Static member functions are not associated with any object. When called, they have no this pointer.
You should have simply written.
std::thread(&Chronometer::start_chrono, std::ref(chrono));
This is my (simplified) code where I'm trying to call async forwarding arguments:
template<typename Ret, typename ... Args>
class CallbackAsyncTask {
public:
CallbackAsyncTask() {
}
virtual ~CallbackAsyncTask() = default;
void execute( Args&& ... args ) {
execute(&CallbackAsyncTask<Ret, Args...>::onBackground, this, std::forward<Args>(args)...);
}
protected:
virtual Ret onBackground( Args& ... args ) = 0;
template<typename Fn, typename ... Argss>
void execute( Fn&& fn, Argss&& ... args ) noexcept(false) {
std::async(std::launch::async, std::forward<Fn>(fn), std::forward<Argss>(args)...);
}
};
class Child: public CallbackAsyncTask<int, int> {
public:
virtual int onBackground( int& i ) {
return i;
}
};
int main() {
Child c;
c.execute(15);
return 0;
}
I get this error:
../main.cpp: In instantiation of ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’:
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
../main.cpp:33:90: error: no matching function for call to ‘async(std::launch, int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>* const, int)’
std::async(std::launch::async, std::forward<Fn>(fn), std::forward<Argss>(args)...);
^
../main.cpp:33:90: note: candidates are:
In file included from ../main.cpp:13:0:
/usr/include/c++/4.8.2/future:1532:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8.2/future:1532:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8.2/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (CallbackAsyncTask<int, int>::*)(int&); _Args = {CallbackAsyncTask<int, int>* const, int}]’:
../main.cpp:33:90: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1532:5: error: no type named ‘type’ in ‘class std::result_of<int (CallbackAsyncTask<int, int>::*(CallbackAsyncTask<int, int>*, int))(int&)>’
../main.cpp: In instantiation of ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’:
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1552:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...)
async(_Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8.2/future:1552:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8.2/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>* const, int}]’:
../main.cpp:33:90: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1552:5: error: no type named ‘type’ in ‘class std::result_of<std::launch(int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>*, int)>’
What I am missing? Compiler Gcc 4.8.3
The root cause is these two lines
virtual Ret onBackground( Args& ... args ) = 0;
virtual int onBackground( int& i )
When launching the task, the arguments are converted either directly or as if by the std::thread constructor. That one does decay_copy on the arguments when invoking the callable, so a non-const lvalue reference cannot bind to the argument.
Change the way onBackground accepts arguments. For instance, a const lvalue refernce works. See live.
This question already has answers here:
Start thread with member function
(5 answers)
Passing object by reference to std::thread in C++11
(4 answers)
Closed 3 years ago.
it is kinda late where I am now & I dont have much experience with threading so I may be overlooking something obvious... But I made a small example of what my error is :
Source Code :
#include <thread>
struct B {
/* Stuff */
};
struct A {
std::thread td;
A(const B& b) { td = std::thread(&A::f, b); }
void f(const B& b) { /* DO SOMETHING WTIH b */ }
};
int main() {
B b;
A a(b);
}
Compiling with g++ -c smallex.cpp and I dont really understand what my issue is here. I think it is pretty straight forward what I am trying to accomplish here..
In file included from smallex.cpp:1:0:
/usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >’:
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(const B&); _Args = {const B&}]’
smallex.cpp:11:42: required from here
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >::_M_invoke(std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (A::*)(const B&), B>]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
/usr/include/c++/7/thread:231:4: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1}]’:
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(const B&); _Args = {const B&}]’
smallex.cpp:11:42: required from here
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (A::*)(const B&), B> >, std::__tuple_element_t<1, std::tuple<void (A::*)(const B&), B> >)’
-> decltype(std::__invoke(_S_declval<_Ind>()...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/tuple:41:0,
from /usr/include/c++/7/bits/unique_ptr.h:37,
from /usr/include/c++/7/memory:80,
from /usr/include/c++/7/thread:39,
from smallex.cpp:1:
/usr/include/c++/7/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/include/c++/7/bits/invoke.h:89:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(const B&); _Args = {B}]’:
/usr/include/c++/7/thread:233:29: required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1}]’
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (A::*)(const B&), B> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(const B&); _Args = {const B&}]’
smallex.cpp:11:42: required from here
/usr/include/c++/7/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<void (A::*)(const B&), B>’
Can someone please help point me in the right direction?
Notes :
g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I'm trying to use std::bind to call std::reference_wrapper::get but I can't get it to compile. I'm sure I'm overlooking something obvious but the compiler errors are not helping me out. This code is contrived and doesn't represent my actual use case:
#include <functional>
#include <iostream>
struct A
{
void p() {std::cout << this << '\n';};
};
using ARef = std::reference_wrapper< A >;
int main()
{
A a;
a.p();
auto p = std::bind (&A::p, std::placeholders::_1);
p (a); // ok
ARef ar (a);
p (ar.get()); // ok
auto get = std::bind (&ARef::get, std::placeholders::_1);
p (get (ar)); // error
}
Edit: This compiles fine with clang.
gcc 6.3.0 output: http://coliru.stacked-crooked.com/a/00bffc7549193cb8
main.cpp: In function 'int main()':
main.cpp:21:19: error: no match for call to '(std::_Bind<std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>(std::_Placeholder<1>)>) (ARef&)'
p (get (ar)); // error
^
In file included from main.cpp:1:0:
/usr/local/include/c++/6.3.0/functional:989:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}]
operator()(_Args&&... __args)
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:989:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional:985:39: error: no match for call to '(std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)'
= decltype( std::declval<_Functor&>()(
~~~~~~~~~~~~~~~~~~~~~~~~~^
_Mu<_Bound_args>()( std::declval<_Bound_args&>(),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
std::declval<tuple<_Args...>&>() )... ) )>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:985:39: required from here
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)'
-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]'
/usr/local/include/c++/6.3.0/functional:985:39: required from here
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>'
/usr/local/include/c++/6.3.0/functional:1003:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:1003:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional:999:53: error: no match for call to '(const std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)'
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typename add_const<_Functor>::type&>::type>()(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:999:53: required from here
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)'
-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]'
/usr/local/include/c++/6.3.0/functional:999:53: required from here
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>'
/usr/local/include/c++/6.3.0/functional:1017:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}]
operator()(_Args&&... __args) volatile
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:1017:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional:1013:70: error: no match for call to '(volatile std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)'
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typename add_volatile<_Functor>::type&>::type>()(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:1013:70: required from here
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)'
-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]'
/usr/local/include/c++/6.3.0/functional:1013:70: required from here
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>'
/usr/local/include/c++/6.3.0/functional:1031:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>; _Bound_args = {std::_Placeholder<1>}]
operator()(_Args&&... __args) const volatile
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:1031:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional:1027:64: error: no match for call to '(const volatile std::_Mem_fn<A& (std::reference_wrapper<A>::*)() const noexcept>) (std::reference_wrapper<A>&)'
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typename add_cv<_Functor>::type&>::type>()(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/local/include/c++/6.3.0/functional:600:2: note: candidate: template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _MemFunPtr = A& (std::reference_wrapper<A>::*)() const noexcept; bool __is_mem_fn = true]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:600:2: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:1027:64: required from here
/usr/local/include/c++/6.3.0/functional:603:27: error: no matching function for call to '__invoke(A& (std::reference_wrapper<A>::* const&)() const noexcept, std::reference_wrapper<A>&)'
-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: candidate: template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/local/include/c++/6.3.0/functional:245:5: note: template argument deduction/substitution failed:
/usr/local/include/c++/6.3.0/functional: In substitution of 'template<class _Callable, class ... _Args> typename std::result_of<_Callable&&(_Args&& ...)>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = A& (std::reference_wrapper<A>::* const&)() const noexcept; _Args = {std::reference_wrapper<A>&}]':
/usr/local/include/c++/6.3.0/functional:603:27: required by substitution of 'template<class ... _Args> decltype (std::__invoke(((const std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>*)this)->std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::_M_pmf, (forward<_Args>)(std::_Mem_fn_base::operator()::__args)...)) std::_Mem_fn_base<_MemFunPtr, __is_mem_fn>::operator()(_Args&& ...) const [with _Args = {std::reference_wrapper<A>&}]'
/usr/local/include/c++/6.3.0/functional:1027:64: required from here
/usr/local/include/c++/6.3.0/functional:245:5: error: no type named 'type' in 'class std::result_of<A& (std::reference_wrapper<A>::* const&(std::reference_wrapper<A>&))() const noexcept>'
It is illegal to take the address of standard library member functions, because implementations can add overloads and mutilate their signatures at will. Therefore, the standard library, and in particular the INVOKE protocol used by bind and friends, is designed around the assumption that it won't be passed a pointer to member of std::reference_wrapper. Invoking a pointer to member pm with a reference_wrapper r is equivalent to invoking pm with r.get(); i.e., the reference is unconditionally unwrapped.
See also LWG issue 2219, which added reference_wrapper handling to INVOKE.