std :: bind一个绑定的函数 [英] std::bind a bound function

查看:336
本文介绍了std :: bind一个绑定的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在检测为什么这是不编译的麻烦。我有一些lambda函数返回一个 std :: function 基于一些参数。

I'm having trouble in detecting why the heck is this not compiling. I've got some lambda function that returns a std::function based on some argument.

我已将问题范围缩小到此程式码片段(不使用lambdas,但完全重现错误):

I've narrowed down my problem to this snippet(which doesn't use lambdas, but reproduces my error perfectly):

#include <functional>
#include <iostream>


struct foo {
    template<class T>
    void bar(T data) {
        std::cout << data << "\n";
    }
};

void some_fun(const std::function<void(int)> &f) {
    f(12);
}

int main() {
    foo x;
    auto f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
    auto w = std::bind(some_fun, f);
    w();
}

调用 w()产生那些可爱的gcc错误输出之一,其中我不能弄清楚出了什么问题。这是gcc 4.6.1回显的错误:

The call to w() produces one of those lovely gcc error outputs in which I can't figure out what's going wrong. This is the error echoed by gcc 4.6.1:

g++ -std=c++0x    test.cpp   -o test
test.cpp: In function ‘int main()’:
test.cpp:20:7: error: no match for call to ‘(std::_Bind<void (*(std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>))(const std::function<void(int)>&)>) ()’
/usr/include/c++/4.6/functional:1130:11: note: candidates are:
/usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]

这里, f 应该是一个可调用的对象,它接受一个int作为参数,并调用 x.bar(int)使用它。另一方面, w 只是一个可调用的对象,它调用 some_fun(f) f 上面提到的可调用对象,它具有 some_fun 的参数预期的签名。

Here, f should be some callable object which takes an int as argument and calls x.bar(int) using it. On the other hand, w is just a callable object which calls some_fun(f), being f the callable object mentioned above, which has the signature expected by some_fun's parameter.

我错过了什么?我可能不知道如何实际混合 std :: bind std :: function

Am I missing something? I probably don't know how to actually mix std::bind and std::function.

推荐答案

boost :: bind 前缀,支持一种类型的组合(例如: std :: bind 操作。 w 的表达式大致等同于

std::bind expressions, like their boost::bind predecessors, support a type of composition operation. Your expression for w is roughly equivalent to

auto w=std::bind(some_fun,  std::bind(&foo::bar<int>, x, std::placeholders::_1) );

以这种方式嵌套绑定被解释为

Nesting binds in this manner is interpreted as


  1. 计算 x.bar< int>(y)的值 y



  1. Calculate the value of x.bar<int>(y) where y is the first parameter passed into the resulting functor.
  2. Pass that result into some_fun.


    x.bar< int>(y)返回void,而不是任何函数类型。这就是为什么这不编译。

But x.bar<int>(y) returns void, not any function type. That's why this doesn't compile.

正如K-ballo指出,用 boost :: bind 可以用 boost :: protect 修复这个问题。正如Kerrek SB和ildjarn指出的,解决这个问题的一个方法是:不要使用 auto f 。您不希望 f 具有绑定表达式的类型。如果 f 有一些其他类型,则 std :: bind 将不会尝试应用函数组合规则。例如,你可以给 f 类型 std :: function< void(int)>



As K-ballo points out, with boost::bind, you can fix this problem with boost::protect. As Kerrek SB and ildjarn point out, one way around this issue is: don't use auto for f. You don't want f to have the type of a bind expression. If f has some other type, then std::bind won't attempt to apply the function composition rules. You might, for instance, give f the type std::function<void(int)>:

std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);

由于 f 类型的绑定表达式, std :: is_bind_expression<> :: value 将在 f ,因此第二行中的 std :: bind 表达式只是逐字传递值,而不是尝试应用函数组合规则。

Since f doesn't literally have the type of a bind expression, std::is_bind_expression<>::value will be false on f's type, and so the std::bind expression in the second line will just pass the value on verbatim, rather than attempting to apply the function composition rules.

这篇关于std :: bind一个绑定的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆