-1

Goal : Obtain a callback function that will take any type of parameters as the callback function's parameters

.h
template <typename F, typename A>
void DelayedCallback(F&& CallbackFunction, A&& Args = NULL);

/

.cpp
void DelayedCallback(F&& CallbackFunction, A&& Args)
{
  //Timer function that received a function pointer to be the "callback"  function
  Timer((std::bind(std::forward<F>(CallbackFunction), std::forward<A>(Args)))())
}

/

DelayedCallback(&HUDExit);

void HUDExit() {}

/

ERROR : DelayedCallback(FName,float,F &&,A &&)' : could not deduce template argument for 'A'

What am I doing wrong? I'm new to most of these concept in c++, more of c# programmer

EDIT : It's not only about the error, I'm pretty sure it's not the only one I am making.

Fawar
  • 735
  • 2
  • 11
  • 32
  • 1. Don't implement template functions in separate translation units. 2. Don't miss the `template` prefixes with their implementation. – πάντα ῥεῖ Jun 04 '15 at 16:42
  • Everything should therefore be in the .h . What do you mean by don't miss the template prefixes with their implementation? – Fawar Jun 04 '15 at 16:44
  • _"What do you mean by don't miss the template prefixes ..."_ `template void DelayedCallback(F&& CallbackFunction, A&& Args) { /* ... */ }` i mean for the definition. – πάντα ῥεῖ Jun 04 '15 at 16:46
  • 1
    @πάνταῥεῖ Somehow I doubt *could not deduce template argument for 'A'* is being caused because the OP placed the implementation in a cpp file. – Praetorian Jun 04 '15 at 16:49

1 Answers1

1

Your error message doesn't match the signature of DelayedCallback

template <typename F, typename A>
void DelayedCallback(F&& CallbackFunction, A&& Args = NULL)

DelayedCallback(&HUDExit);

That function signature and the usage you've shown will not produce an error message that says

ERROR : DelayedCallback(FName,float,F &&,A &&)' : could not deduce template argument for 'A'

But ignoring the template parameter mismatches, the code you've shown will also result in a similar error. The problem is that template parameters cannot be deduced from default arguments and A is treated as a non-deduced context in your example.

From N3337, §14.8.2.5/5 [temp.deduct.type]

The non-deduced contexts are:
...
— A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.

Instead, you should change A to a parameter pack. That'll allow you to pass zero or more arguments to DelayedCallback.

template <typename F, typename... A>
void DelayedCallback(F&& CallbackFunction, A&&... Args)
{
  //Timer function that received a function pointer to be the "callback"  function
  Timer((std::bind(std::forward<F>(CallbackFunction), std::forward<A>(Args)...))())
  // previous line is missing a semicolon at the very least
}

Once you fix all that, you'll run into the problem mentioned in the comments. You cannot split the declaration and definition of a function template between a header and source file as you would with a non-template. So implement DelayedCallback in the header itself as I have done above.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Sorry I cut 2 extra parameters that were worthless to the question :S Is there a solution of not using header file? I'm in Unreal SDK (3) and I'm not sure what are the limitations toward this type of usage? – Fawar Jun 04 '15 at 17:25
  • @Fawar No, there aren't any alternatives that are useful in general. It's highly unlikely you'll run into problems implementing a function template in a header, Unreal SDK or otherwise. – Praetorian Jun 04 '15 at 17:42
  • I'll try this and see if I get anything out of it, thank you very much for your help! If what you wrote happens to help me out or make it work I will accept your answer and post the result of what I built around this – Fawar Jun 04 '15 at 17:44