c++templatesboost-bind

Binding callback to a templated object


I have a templated class that holds a callback, stored as a std::function

typedef std::function<void()> func_t;

template<typename T>
struct A
{
   T someMember;
   func_t callback;
};

This callback is called by some mechanism (boost::asio) and I want to pass arguments, so I bind them:

For example:

void a_callback( int v )
{
    std::cout << "value=" << v << "\n";
}

and I store it in the object that way.

enum EN { ONE, TWO };

int main()
{
    A<EN> a;

    a.callback = boost::bind( a_callback, 42); // ok
    a.callback(); // ok
}

So far, all good.

But now I want to pass the object itself to the callback function, so that it can do things on it. The callback becomes templated, as the object class is:

template<typename T>
void b_callback( A<T>& b, int v )
{
    std::cout << "value=" << v << "\n";
}

But attempting to bind it fails:

int main()
{
    A<EN> a2;  
    a2.callback = boost::bind( b_callback, a2, 42); 
}

Clang says:

error: no matching function for call to 'bind'
    a2.callback = boost::bind( b_callback, a2, 42); // build error
/usr/local/include/boost/bind/bind.hpp:1891:5: note: candidate template ignored: couldn't infer template argument 'R'
    BOOST_BIND(F f, A1 a1, A2 a2)
/usr/local/include/boost/bind/bind.hpp:1868:20: note: expanded from macro 'BOOST_BIND'
#define BOOST_BIND bind

Full code here (coliru)

What did I do wrong ? How can I manage that ?


Solution

  • You need to instantiate a function template with a concrete type EN:

    a2.callback = boost::bind(&b_callback<EN>, a2, 42);
    

    as b_callback is a function template, not a function.

    EXAMPLE