Search code examples
c++templatesboostlinkerboost-bind

Boost undefined reference error with boost::bind overloaded operators


The code in question:

boost::function<bool()> isSpecialWeapon = boost::bind(&WeaponBase::GetType,this) == WeaponType::SPECIAL_WEAPON;

The error I get is something like so:

 undefined reference to `boost::_bi::bind_t<bool, boost::_bi::equal, 
 boost::_bi::list2<boost::_bi::bind_t<WeaponType::Guns, 
 boost::_mfi::cmf0<WeaponType::Guns, WeaponBase>,  
 boost::_bi::list1<boost::_bi::value<WeaponBase*> > >, 
 boost::_bi::add_value<WeaponType::Guns>::type> > boost::_bi::operator==
 <WeaponType::Guns, boost::_mfi::cmf0<WeaponType::Guns, WeaponBase>, 
 boost::_bi::list1<boost::_bi::value<WeaponBase*> >, WeaponType::Guns>
 (boost::_bi::bind_t<WeaponType::Guns, boost::_mfi::cmf0<WeaponType::Guns, WeaponBase>, 
 boost::_bi::list1<boost::_bi::value<WeaponBase*> > > const&, WeaponType::Guns)'

Solution

  • If you can't get boost::bind to work as you desire, you can try Boost.Pheonix or Boost.Lamda as a workaround.

    Try using boost::pheonix::bind (from Boost.Pheonix) instead of boost::bind:

    #include <boost/phoenix/operator.hpp>
    #include <boost/phoenix/bind/bind_member_function.hpp>
    #include <boost/function.hpp>
    #include <iostream>
    
    enum WeaponType {melee, ranged, special};
    
    class Sword
    {
    public:
        WeaponType GetType() const {return melee;}
    
        void test()
        {
            namespace bp = boost::phoenix;
            boost::function<bool()> isSpecialWeapon =
                bp::bind(&Sword::GetType, this) == special;
            std::cout << "isSpecialWeapon() = " << isSpecialWeapon() << "\n";
        }
    
    };
    
    int main()
    {
        Sword sword;
        sword.test();
    }
    

    Alternatively, you also use boost::lambda::bind (from Boost.Lambda):

    #include <boost/function.hpp>
    #include <boost/lambda/bind.hpp>
    #include <boost/lambda/lambda.hpp>
    #include <iostream>
    
    enum WeaponType {melee, ranged, special};
    
    class Sword
    {
    public:
        WeaponType GetType() const {return melee;}
    
        void test()
        {
            boost::function<bool()> isSpecialWeapon =
                boost::lambda::bind(&Sword::GetType, this) == special;
            std::cout << "isSpecialWeapon() = " << isSpecialWeapon() << "\n";
        }
    
    };
    
    int main()
    {
        Sword sword;
        sword.test();
    }