Search code examples
c++c++11boostfunctorboost-bind

boost::bind with templated functors


Just trying to get this simple test working for accessing the function operator. I have dug around the boost::bind (esp for the overloaded section ) but have not found a way to get this to work.

#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;

}

Compiler output:

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
                           ^

I know I am just missing something simple, any help would be awesome.


Solution

  • You're attempting to take the address of a member function template without specifying the type arguments, which is not possible. Your code works if you add the type arguments for both Foo and operator().

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

    But, as T.C. says in the comments, you already have a functor which can be bound directly as

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

    Live demo