c++ - std::bind 绑定(bind)函数

标签 c++ function c++11 bind

我无法检测为什么这根本无法编译。我有一些 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只是一个调用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) );

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

  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具有绑定(bind)表达式的类型。如果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字面上没有绑定(bind)表达式的类型,std::is_bind_expression<>::valuef 上将为假的类型,所以 std::bind第二行中的表达式将逐字传递值,而不是尝试应用函数组合规则。

关于c++ - std::bind 绑定(bind)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30033463/

相关文章:

c# - 在 c++/c# 中从哪里开始抓取/爬行?

c++ - 结构参数的默认值

c++ - 二叉搜索树分析

c++ - 我可以在 VS2010 中获取 VS2012 标准库吗

C++11 枚举类包含重复值

C++使用数组中的类执行函数

不同类型 vector 上的 C++ 相同函数

function - Haskell - 将函数元组应用于值元组?

c++ - 从文件中搜索字符串的函数

C++/OpenGL : How does Tesselation work?