I thought I had a hold on std::bind
, but the compiler has me stumped on this one. Currently compiling with c++17.
I have a generic way of binding a function to a bunch of arguments so that it can be called later with no arguments. This is NoParameterBinding
, works fine.
I have a generic way of binding a function to a bunch of arguments, leaving the first argument open with std::placeholders
. This is SingleParameterBinding
, works fine.
An intermediate static struct is now going to do some calls for me. I pass it the same arguments I would pass SingleParameterBinding
, and it forwards the arguments. This is BindRequest::bindOnce
, works fine.
Lastly, I want to package that last function up using NoParameterBinding
. BindRequest::bindTwice
will do this for me. It calls NoParameterBinding
, passes the bindOnce
function, and forwards the arguments. This fails.
What gives? I’m passing a function along with all the arguments it needs, but the compiler insists it can’t convert things to std::function<void()>
:
forwarding.cpp:10:38: error: conversion from ‘std::_Bind_helper<false, void (&)(void (&)(const long int&, const double&), double&&), void (&)(const long int&, const double&), double>::type’ to non-scalar type ‘NoParameterBinding::Task’ {aka ‘std::function<void()>’} requested
Here is the code in question:
#include<functional>
struct NoParameterBinding
{
using Task = std::function<void()>;
template<typename FuncType, typename... Args>
static void bind(FuncType&& func, Args&&... args)
{
Task task = std::bind(std::forward<FuncType>(func), std::forward<Args>(args)...);
}
};
struct SingleParameterBinding
{
using CallbackType = std::function<void(long)>;
template<typename FuncType, typename... Args>
static void bind(FuncType&& callbackFunc, Args&&... args)
{
CallbackType callback = std::bind(std::forward<FuncType>(callbackFunc), std::placeholders::_1, std::forward<Args>(args)...);
}
};
struct BindRequest
{
using CallbackType = SingleParameterBinding::CallbackType;
template<typename CallbackFuncType, typename... CallbackArgs>
static void bindOnce(CallbackFuncType&& callback, CallbackArgs&&... callbackArgs)
{
SingleParameterBinding::bind(std::forward<CallbackFuncType>(callback), std::forward<CallbackArgs>(callbackArgs)...);
}
template<typename CallbackFuncType, typename... CallbackArgs>
static void bindTwice(CallbackFuncType&& callback, CallbackArgs&&... callbackArgs)
{
NoParameterBinding::bind(BindRequest::bindOnce<CallbackFuncType, CallbackArgs...>, std::forward<CallbackFuncType>(callback), std::forward<CallbackArgs>(callbackArgs)...);
}
};
void exampleCallback(const long& l, const double& d)
{
return;
}
int main()
{
NoParameterBinding::bind(exampleCallback,'a',9.9);
SingleParameterBinding::bind(exampleCallback, 9.9);
BindRequest::bindOnce(exampleCallback, 9.9);
BindRequest::bindTwice(exampleCallback, 9.9); //Why freak out here?
return 0;
}
4