的std ::绑定一个约束函数的std ::绑定一个约束函数(std::bind a bound f

2019-05-16 13:41发布

我在检测故障原因到底是不是这样编译。 我有一个返回一些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

Answer 1:

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指出,解决此问题的一个方法是:不使用autof 。 你不想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的类型,因此std::bind在第二行表达将只传递的值逐字,而不是试图以应用功能的合成规则。



Answer 2:

some_fun希望类型的参数const std::function<void(int)> &

的std ::绑定返回“未指定类型T的函数对象”(看提供的链接,部分“返回值”),你正在试图通过为some_fun说法。

看来这会导致问题,因为这种说法类型不预期。

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



文章来源: std::bind a bound function