c++boostboost-bind

Passing class member function with 2 parameters to boost bind


Boost bind fails to deduce/substitute template argument:

class A
{
  ...
  bool f(boost::shared_ptr<boost::array<unsigned char, 128>>&, size_t);
  ...
};

A myA;
boost::bind(&A::f, &myA, _1, _2);

I am using boost 1.63. The compile error message points to boost_1_63_0/include/boost/bind/bind.hpp:

template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
{    
    return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
}    


Solution

  • You should make the code self-contained:

    https://godbolt.org/z/WefoWa9df

    #include <boost/array.hpp>
    #include <boost/bind/bind.hpp>
    #include <boost/make_shared.hpp>
    #include <boost/shared_ptr.hpp>
    #include <iostream>
    
    using b128 = boost::array<unsigned char, 128>;
    
    class A {
      public:
        bool f(boost::shared_ptr<b128>& d, size_t) {
            std::cout << "called with '" << d->at(0) << "'" << std::endl;
            return false;
        }
    };
    
    int main() {
        A myA;
    
        using namespace boost::placeholders;
        auto f = boost::bind(&A::f, &myA, _1, _2);
    
        auto x = boost::make_shared<b128>();
        x->fill('\x55'); // 'U'
    
        f(x, 0);
    }
    

    Printing

    called with 'U'
    

    Guessing

    My best guess is that you're mixing boost::placeholders and std::placeholders:

    // using namespace boost::placeholders;
    using namespace std::placeholders;
    auto f = boost::bind(&A::f, &myA, _1, _2);
    

    See it on https://godbolt.org/z/ecK8aYjv9

    /opt/compiler-explorer/libs/boost_1_64_0/boost/bind/bind.hpp:388:42: error: no match for call to '(boost::_mfi::mf2<bool, A, boost::shared_ptr<boost::array<unsigned char, 128> >&, long unsigned int>) (A*&, std::_Placeholder<1>&, std::_Placeholder<2>&)'
      388 |         return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
          |                ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    BONUS

    Modernize, not using Boost at all:

    #include <functional>
    #include <iostream>
    #include <memory>
    
    using b128 = std::array<unsigned char, 128>;
    
    class A {
      public:
        bool f(std::shared_ptr<b128> const& d, size_t) const {
            std::cout << "called with '" << d->at(0) << "'" << std::endl;
            return false;
        }
    };
    
    int main() {
        A myA;
    
        using namespace std::placeholders;
        auto f = bind(&A::f, &myA, _1, _2);
    
        auto x = std::make_shared<b128>();
        x->fill('\x32'); // '2'
    
        f(x, 0);
    }