manabreak
manabreak

Reputation: 5597

How to use function pointer as a constructor argument for a templated class?

I'm trying to pass a function pointer as an argument to an object that is created using a templated function, but I get this error when I try to do that:

error C2664: cannot convert argument 1 from
    'void (__thiscall Northland::Sword::*)(Tecs::Entity&)' to 
    'void (__cdecl *)(Tecs::Entity&)'

The line that originates this is this:

// In Sword constructor
m_entity.addComponent<Touchable>(&Sword::startTouch);

The addComponent<>() method is like this (non-relevant stuff omitted):

template<class T, class... Params)
T& addComponent(Entity& entity, Params&&... params)
{
    // ...
    // Retrieves the next free memory portion
    T* t = Pooler<T>::instance().getNext();
    // Constructs the new T - this is where MSVC points when the error happens
    t = new(t) T(std::forward<Params>(params)...);
    // ...
}

Finally, the Touchable class looks like this:

class Touchable : public Tecs::Component
{
public:
    Touchable(void(*touchFunc)(Tecs::Entity&))
      : m_touchFunc(touchFunc)
    {

    }

    void startTouch(Tecs::Entity& other)
    {
        (*m_touchFunc)(other);
    }

private:
    void(*m_touchFunc)(Tecs::Entity&);
};

What could be the cause of the problem here?

Upvotes: 0

Views: 99

Answers (1)

ForEveR
ForEveR

Reputation: 55887

It's member function pointer, not function pointer. So you should pass object too. You can use std::bind for this and in Touchable use std::function, instead of raw function pointer.

m_entity.addComponent<Touchable>
(
   std::bind(&Sword::startTouch, std::ref(sword_object))
);

Upvotes: 1

Related Questions