I have the following code using variadic templates to call std::async,
struct TestParent
{
template< typename Fn, typeName ...Args >
bool checkBlock( bool& toCheck,
Fn&& fn, Args&& ... args )
{
int startIndx = 0;
int endIndx = 10;
std::future< bool > tk( std::async( std::launch, fn, this,
startIndx, endIndx,
toCheck, args ... ) );
return tk.get();
}
}
struct TestChild: public TestParent
{
bool checkRules( const int, const int, bool& std::vector< bool >& );
bool check();
}
bool TestChild::checkRules( const int startIndx, const int endIndx,
bool& toCheck,
std::vector< bool >& results )
{
toCheck = true;
for ( int indx = startIndx; indx < endIndx; ++ indx )
{
bool checkedOk;
... do something checking.
results.push_back( checkedOk );
}
return true;
}
bool TestChild::check()
{
bool toCheck;
std::vector< bool > results;
return checkBlock( toCheck, &testChild::checkRules, this, &results);
}
But I'm getting the following compilation error message:
no matching function for call to 'async(std::launch, bool (TestChild::&)(int, int, bool&, std::vector&), TestParent, int&, int&, bool&, TestChild*&, std::vector*&)' startInx, endInx, nothingToCheck, args ... ) );
I think it might have something to do with the fact that I'm passing additional parameters along with a parameter pack. Anyone has any ideas what's wrong with this, and what I should do to get this to work?
These are the two main issues in the code:
(1) std::async
decay all the passed argument before forwarding them to the provided function, this mean that the references parameter in checkRules
differ from the type async
is trying to use when invoking the function, you need to do the following change:
template< typename Fn, typename ...Args >
bool checkBlock( std::reference_wrapper<bool> const& toCheck,
Fn&& fn, Args&& ... args )
{
int startIndx = 0;
int endIndx = 10;
std::future< bool > tk(std::async(std::launch::async,
std::forward<Fn>(fn),
startIndx, endIndx,
toCheck,
std::forward<Args>(args) ... ) );
return tk.get();
}
(2) You're passing this
as argument to checkBlock
which eventually will end up as argument of checkRules
(by async call), but the member function doesn't accept TestChild*
to match this
. Since you're using a pointer to member function to async
you need to use std::bind
to bind the this
arguments and use std::wrap
for the arguments you want to change:
#include <functional>
using namespace std::placeholders;
bool TestChild::check()
{
bool toCheck;
std::vector< bool > results;
return checkBlock( std::ref(toCheck), std::bind(&TestChild::checkRules, this, _1, _2, _3, _4), std::ref(results));
}