【问题标题】:std::bind with variable function arguments including a callback function with variable arguments带有可变函数参数的 std::bind,包括带有可变参数的回调函数
【发布时间】:2019-03-12 15:03:37
【问题描述】:

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

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

上面的函数正在使用未来从一个单独的类中调用:

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’

【问题讨论】:

  • 您是否考虑过使用 lambda 代替? (再想一想:你可能需要 C++14)
  • 这是一个纯粹的学术问题,还是您试图让某些东西发挥作用?如果是后者,答案很简单:只需使用 lambda。
  • 我正在尝试让某些东西正常工作。使用 lambda 的唯一问题是带有变量 args 的函数是公共库的一部分。所以把它变成一个 lambda 并将它放在我调用它的类中是不可行的。
  • @PK17 我不清楚为什么将 lambda 放在一个类中不如 std::bind 可行。
  • @eerorika 正如我提到的,CallWithArgs fn 是公共库的一部分,需要访问该公共库中的其他函数/变量。我计划进一步允许支持从其他组件/可执行文件调用该函数。不希望每个组件都实现与 lambda 函数相同的 fn CallWithArgs。

标签: c++ c++11 variadic-functions stdbind


【解决方案1】:

由于您不能使用 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();

【讨论】:

  • 升级到 c++14 会很好,是的 :) 但不幸的是,目前还不可能。将尝试您使用仿函数的建议并在此处更新。谢谢!
  • @PK17 没问题。让我知道它是否适合您。
  • 谢谢@NathanOliver 你的建议奏效了。还创建了一个单独的测试文件来尝试 C++14 的方式,它也可以工作!
  • @PK17 太棒了。很高兴它对你有用。希望有一天你可以升级:)
猜你喜欢
  • 2013-11-10
  • 2019-01-18
  • 2019-04-30
  • 2016-03-31
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多