std::bind 具有可变参数的函数,包括具有可变参数的回调函数

std::bind with variable function arguments including a callback function with variable arguments

如果我有一个带有可变参数的函数,其中一个是回调函数,那么该函数的绑定函数将如何工作? 当前实现如下:

template <typename... Args>
bool CallWithArgs(std::function<void (String&, Args... args)> cbk, Args... args) 
{ .... }

正在使用未来从单独的 class 调用上述函数:

bool value = true;
auto f1 = std::bind(&CallWithArgs, rawPtr, _1, _2);
std::future<bool> fut = std::async(f1, cbk, value);
fut.wait();

std::bind 函数的占位符中是否有表示可变参数的方法? 运行 进入当前实现的编译问题。

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’

由于您不能使用 C++14 的通用 lambda,您可以通过制作仿函数来制作自己的 lambda。如果你有

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)...)
    }
};

然后你可以像

一样在你的代码块中使用它
bool value = true;
std::future<bool> fut = std::async(CallWithArgsFunctor{rawPtr}, cbk, value);
fut.wait();

这允许重载决策在调用运算符的主体中工作,而不必将函数指针强制转换为要调用的类型。


如果您可以升级到 C++14,您的代码就会变成

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();