【发布时间】: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&& f, BoundArgs&&... bound_args):INVOKE(fd, w1, w1, ..., wN)应该是有效的某些值的表达式 w1, w2, ..., wN,其中N == sizeof...(bound_args)(但 IIRC 绑定表达式有一些例外...) -
嗯...有一个例外允许你写一些相当愚蠢的东西,比如
struct wrapper { template<class... Args> int operator()(Args... args) { process(args...); return 42; } }; namespace std { template<> struct is_bind_expression<wrapper> : 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