繁体   English   中英

std :: bind绑定函数

[英]std::bind a bound function

我在确定为什么无法编译时遇到了麻烦。 我有一些lambda函数,它基于某些参数返回std::function

我将问题缩小到此代码段(不使用lambda,但完美地再现了我的错误):

#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只是一个可调用对象,它调用上文提到的可调用对象fsome_fun(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) );

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

  1. 计算x.bar<int>(y)的值,其中y是传递到结果函子的第一个参数。
  2. 将该结果传递给some_fun

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

正如K-ballo指出的那样,使用boost::bind可以使用boost::protect解决此问题。 正如Kerrek SB和ildjarn所指出的,解决此问题的一种方法是:不要将auto用于f 您不希望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<>::valuef的类型上为false,因此第二行的std::bind表达式仅将值传递给逐字记录,而不是尝试应用功能组合规则。

some_fun想要使用const std::function<void(int)> &类型的参数。

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

看来这会引起问题,因为不需要此参数类型。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM