【问题标题】:Can bind be used to forward a variadic number of arguments?可以使用绑定来转发可变数量的参数吗?
【发布时间】:2014-07-14 20:25:49
【问题描述】:

在 C++14 中,我可以编写一个对任意数量的参数进行完美转发的 lambda:

template<typename... Args>
void process(Args&&... args);                       // template to forward to


auto wrapper = [](auto&&... args) 
{ 
  std::cout << "Invoking lambda wrapper\n";
  process(std::forward<decltype(args)>(args)...);   // do the forwarding
};

有没有办法使用bind达到同样的效果?我知道bind 创建的函数对象采用任意数量的参数,并且我知道这些对象对未绑定的参数使用完美转发,但是有没有办法告诉bind 创建一个使用完美转发的函数对象传递给它的每个参数,即使在对 bind 的调用中没有占位符?

【问题讨论】:

  • o.O [c++1y] 标签甚至不提供自动语法高亮。
  • 我认为一般来说不可能:[func.bind.bind]/2 需要 bind(F&amp;&amp; f, BoundArgs&amp;&amp;... bound_args)INVOKE (fd, w1, w1, ..., wN) 应该是有效的某些值的表达式 w1, w2, ..., wN,其中 N == sizeof...(bound_args)(但 IIRC 绑定表达式有一些例外...)
  • 嗯...有一个例外允许你写一些相当愚蠢的东西,比如struct wrapper { template&lt;class... Args&gt; int operator()(Args... args) { process(args...); return 42; } }; namespace std { template&lt;&gt; struct is_bind_expression&lt;wrapper&gt; : true_type {}; } void bar(int) {} int main() { auto b = std::bind(bar, wrapper()); b(1); b(1,2.0); }
  • 但一般来说,问题在于将一组重载函数作为参数传递给函数。这只能作为具有重载 operator() 的函数对象——一个 lambda 或手动编写的函数对象。 (好的,对于有限集,您还可以编写愚蠢的包装器单独传递每个重载。)
  • 这是我所说的例外:因为 wrapper 被识别为绑定表达式(因为 trait 特化),一个特殊规则适用于 auto b = bind(bar, wrapper()):所有参数传递给 @ 987654334@ 被转发到绑定的绑定表达式(这里:wrapper() 的副本),调用绑定的绑定表达式,并将结果作为bar 的参数。这有点奇怪,因为任何剩余的参数也会被转发到bar,所以它们可能会被转发多次。

标签: c++ c++14 perfect-forwarding stdbind


【解决方案1】:

目前不可能,但请参阅 http://cplusplus.github.io/EWG/ewg-complete.html#44 以获得支持它的建议:

随着越来越多的可变参数函数进入我的 C++ 代码,我越来越恼火的是没有可变参数绑定。确切地使用什么有点烦恼。在我看来,有 2 个明智的选择(其他人可能有其他人)

1) _args :使用所有未命名的参数。
2) _3onwards : 从第 3 次开始的所有参数。

我个人没有发现需要多个可变参数范围或更复杂的截断(例如获取最后几个参数),我希望尽可能保持简单!

【讨论】:

    猜你喜欢
    • 2010-11-03
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2020-10-15
    相关资源
    最近更新 更多