std ::绑定一个绑定函数

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

我已经缩小了我的问题到这个片段(它不使用lambdas,但完美地重现了我的错误):

#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回应的错误:

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的参数。

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


std::bind表达式,就像它们的boost::bind前辈一样,支持一种组合操作。 你对w表达大致相当于

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

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

  • 计算x.bar<int>(y)的值,其中y是传递给结果函子的第一个参数。
  • 将该结果传递给some_fun
  • 但是x.bar<int>(y)返回void,而不是任何函数类型。 这就是为什么这不编译。

    正如K-ballo指出的那样,使用boost::bind ,你可以用boost::protect来解决这个问题。 正如Kerrek SB和ildjarn指出的那样,解决此问题的一个方法是:不要对f使用auto 。 你不希望f有一个绑定表达式的类型。 如果f有其他类型,则std::bind不会尝试应用函数组合规则。 例如,你可以给f类型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的类型上为false,因此第二行中的std::bind表达式将仅传递该值逐字,而不是尝试应用职能组合规则。


    some_fun需要类型为const std::function<void(int)> &参数const std::function<void(int)> &

    std :: bind返回“未指定类型T的函数对象”(查看提供的链接,“返回值”部分),您尝试将其作为some_fun参数传递。

    看起来这会导致问题,因为这个参数类型不是预期的。

    看看:http://en.cppreference.com/w/cpp/utility/functional/bind

    链接地址: http://www.djcxy.com/p/29757.html

    上一篇: std::bind a bound function

    下一篇: Compiling with gcc fails if using lambda function for QObject::connect()