Search code examples
c++boost

C+/Boost - Signals2 Unable to bind slot that have 1 parameter


I have this code:

namespace VE
{
    template<typename Func>
    using VESignal = boost::signals2::signal<Func>;
}
class NodeManager {
public:
    static VE::VESignal<void(int guid)> NodeDestroyed;
}

And this code:

class  Map : public VE::Nodes::VENode
{
public:
    explicit Map(VE::Nodes::VEId veid);
    virtual ~Map();
    void Initialize() override;
    void RemovePlayer(int guid);
}

Than I do this:

void Map::Initialize()
{
    NodeManager::NodeDestroyed.connect(boost::bind(&Map::RemovePlayer, this, _1));
}

This however does not let me do it. Gives me error:

In template: no matching function for call to object of type 'boost::_mfi::mf1<void, Map, int>' error occurred here in instantiation of function template specialization 'boost::_bi::list2<boost::_bi::value<Map *>, boost::_bi::value<std::_Placeholder<1>>>::operator()<boost::_mfi::mf1<void, Map, int>, boost::_bi::rrlist1<int>>' requested here

Why is that and how can I fix i ?


Solution

  • You're mixing std::placeholders::_1 with boost::bind. Pick one.

    No problem using either:

    Live On Coliru

    #include <boost/signals2.hpp>
    #include <boost/bind/bind.hpp>
    
    #ifdef USE_BOOST_BIND
    using namespace boost::placeholders;
    using boost::bind;
    #else
    using namespace std::placeholders;
    using std::bind;
    #endif
    
    namespace VE {
        template <typename Func> using VESignal = boost::signals2::signal<Func>;
        namespace Nodes {
            struct VEId {
                int guid;
            };
            class VENode {
              public:
                virtual ~VENode() = default;
                virtual void Initialize() = 0;
            };
        }
    }
    
    class NodeManager {
      public:
        static VE::VESignal<void(int guid)> NodeDestroyed;
    };
    
    class Map : public VE::Nodes::VENode {
      public:
        explicit Map(VE::Nodes::VEId veid);
        virtual ~Map();
        void Initialize() override;
        void RemovePlayer(int /*guid*/) {}
    };
    
    VE::VESignal<void(int)> NodeManager::NodeDestroyed;
    
    void Map::Initialize() { NodeManager::NodeDestroyed.connect(bind(&Map::RemovePlayer, this, _1)); }
    
    int main() {
    }
    

    Compiling without problems:

    g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp -DUSE_BOOST_BIND
    g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp