0

So, I have a class called Delegate that can store an array of function pointers. This is the code:

template<typename Func>
class delegate
{
private:
public:
    typename std::vector<Func> mListOfFunctions;
    void Bind(Func f)
    {
        mListOfFunctions.push_back(f);
    }
    template<typename...TArgs>
    void Invoke(TArgs&&...arg)
    {
        for (auto f : mListOfFunctions)
        {
            f(std::forward<TArgs>(arg)...);
        }
    }
};

Usage in Player.cpp:

delegate<void(float)> testDelegate;
testDelegate.Bind(std::bind(&Player::MoveLeft,this));

This throws the error C2893 (Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)')

But when I change the definition of Bind to the following:

template<typename F>    
void Bind(F f)
{

}

It works fine, but when I try to push the function object into the vector it throws the same error again.

Is there anyway to resolve this?

I need to cache the pointers passed in.

VLL
  • 9,634
  • 1
  • 29
  • 54
Ashwin Narayanan
  • 123
  • 1
  • 1
  • 6

1 Answers1

1

The result of std::bind is not a function pointer (it is a function object of an unspecified type), but you're trying to make it into one. Since you're using std::forward, you must be using C++11, which means you can use std::function:

template<typename Func>
class delegate
{
private:
public:
    typename std::vector<std::function<Func>> mListOfFunctions;
    void Bind(std::function<Func> f)
    {
        mListOfFunctions.push_back(f);
    }
    template<typename...TArgs>
    void Invoke(TArgs&&...arg)
    {
        for (auto f : mListOfFunctions)
        {
            f(std::forward<TArgs>(arg)...);
        }
    }
};
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • I changed it to the following and it still throws an error : void Bind(std::function f) { mListOfFunctions.push_back(f); } – Ashwin Narayanan Jun 14 '16 at 16:45
  • Why are you doing that? Why are you not using the code as I posted it? – Dark Falcon Jun 14 '16 at 16:46
  • I did that too : template class delegate { private: public: typename std::vector> mListOfFunctions; void Bind(std::function f) { mListOfFunctions.push_back(f); } template void Invoke(TArgs&&...arg) { for (auto f : mListOfFunctions) { f(std::forward(arg)...); } } }; but when I call Bind it throws that error again – Ashwin Narayanan Jun 14 '16 at 16:51
  • 1
    Compiles perfectly: https://ideone.com/pBJB3P Provide more information. Edit your question and show 1. How you are calling `Bind` 2. The EXACT new error message. – Dark Falcon Jun 14 '16 at 16:54
  • In your case you are not using a member function. But when I try to add a member function using std::bind and pass it as a std::function it throws the same error ( C2893) that was in the question – Ashwin Narayanan Jun 14 '16 at 16:58
  • When i use a lambda or a global/static function it works perfectly. I need it to be able to bind to even a member function – Ashwin Narayanan Jun 14 '16 at 17:00
  • Does your function take arguments? Are you forgetting that when you `std::bind`, you need to use placeholders for the arguments? – Dark Falcon Jun 14 '16 at 17:03
  • Oh I am not sure what placeholders are, but I think that might be it. Thanks for your help – Ashwin Narayanan Jun 14 '16 at 17:09