If I have a function with variable arguments, with one of them being a callback function, how would the bind function for that work? Current implementation as below:
template <typename... Args>
bool CallWithArgs(std::function<void (String&, Args... args)> cbk, Args... args)
{ .... }
The above function is being called from a separate class using a future:
bool value = true;
auto f1 = std::bind(&CallWithArgs, rawPtr, _1, _2);
std::future<bool> fut = std::async(f1, cbk, value);
fut.wait();
Is there anyway to represent variable parameters in the placeholders of the std::bind function? Running into compile issues with the present implementation.
note: template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__or_<std::is_integral<typename std::decay<_Tp>::type>, std::is_enum<typename std::decay<_Tp>::type> >::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _BoundArgs&&... __args)
note: template argument deduction/substitution failed:
note: couldn't deduce template parameter ‘_Func’
Since you can't use C++14's generic lambdas you can make your own by making a functor. If you have
struct CallWithArgsFunctor
{
pointer_type pointer_to_call_on;
CallWithArgsFunctor(pointer_type pointer_to_call_on) : pointer_to_call_on(pointer_to_call_on) {}
template<typename... Args>
auto operator()(Args&&... args) -> decltype(CallWithArgs(pointer_to_call_on, std::forward<Args>(args)...))
{
return CallWithArgs(pointer_to_call_on, std::forward<Args>(args)...)
}
};
then you can use it in your code block like
bool value = true;
std::future<bool> fut = std::async(CallWithArgsFunctor{rawPtr}, cbk, value);
fut.wait();
This allows overload resolution to work in the body of the call operator instead of you having to cast the function pointer to the type you want to call.
If you can upgrade to C++14 your code would just become
bool value = true;
auto f1 = [=](auto&&... args){ return CallWithArgs(rawPtr, std::forward<decltype(args)>(args)...); };
std::future<bool> fut = std::async(f1, cbk, value);
fut.wait();