boost :: bind with templated functors

时间:2014-10-20 22:21:47

标签: c++ c++11 boost functor boost-bind

试图让这个简单的测试用于访问函数运算符。我已经在boost :: bind(overloaded section 的esp)周围进行了挖掘,但还没有办法让它工作。

#include <iostream>

#include <boost/bind.hpp>

template <typename FooType>
struct Foo {
    const FooType tmp_value;

    Foo(const FooType& tmp_) :
    tmp_value(tmp_)
  {
  }

    template<typename Object>
  void operator()(Object& operand)
  {
    std::cout << operand << std::endl;
    operand += tmp_value;
  }
};

int main() {


    double t = 4.0;
    Foo<double> e(1.0);
    std::cout << t << std::endl;
    e(t);   // Works
    std::cout << t << std::endl; 

    double d = 5.0;
    Foo<double> p(1.0);
    auto f1 = boost::bind(&Foo::operator(), p, _1); // Blows up at compile

    std::cout << d << std::endl;
    f1(d); 
    std::cout << d << std::endl;

}

编译器输出:

g++ -Wall --std=c++0x -I.  bind.cc -o binder
bind.cc:33:25: error: expected a class or namespace
    auto f1 = boost::bind(&Foo::operator(), p, _1); // Blows up at compile
                           ^

我知道我只是缺少一些简单的东西,任何帮助都会很棒。

2 个答案:

答案 0 :(得分:4)

您尝试获取成员函数模板的地址而不指定类型参数,这是不可能的。如果为Foooperator()添加类型参数,则代码可以正常工作。

auto f1 = boost::bind(&Foo<double>::operator()<double>, p, _1);
//                        ^^^^^^^^            ^^^^^^^^

但是,正如T.C.在评论中说,你已经有一个可以直接绑定的仿函数

auto f1 = boost::bind<void>(p, _1); // void is the return type of operator()

Live demo

答案 1 :(得分:2)

如评论中所述,您可以绑定p,因为它已经是一个仿函数。是的,它将以多态方式行事,成为它的模板。

但是,根据编译器/升级版本,默认情况下您可能无法获得decltype()良好状态,您必须添加

typedef void result_type;

Foo仿函数类: Live On Coliru

或者,在包含任何提升标题之前,您可以#define BOOST_RESULT_OF_USE_DECLTYPE