8

I was wondering if it is possible to achieve something like this, without an error being thrown:

#include <iostream>

template<typename T>
T Sum(T _arg, T (*callbackFunction)(T))
{
    T result = (*callbackFunction)(_arg);
    return result;
}

template<typename T>
T Callback(T _arg)
{
    std::cout << "Callback is called" << std::endl;
    return _arg;
}

int main()
{
    std::cout << Sum(10.2f, Callback);

    getchar();
    return 0;
}

This is what I get:

cannot use function template 'T Callback(T)' as a function argument
could not deduce template argument for 'T' from 'float'

2 Answers2

6

You can't pass a function template as an argument, you must pass an instantiation, this is an example:

Live On Coliru

#include <iostream>

template<typename T, typename F>
T Sum(T arg, F f)
{
    return f(arg);
}

template<typename T>
T Callback(T arg)
{
    std::cout << "Callback is called" << std::endl;
    return arg;
}

auto Callback2 = [](auto arg)
{
    std::cout << "Callback2, a generic lambda, is called" << std::endl;
    return arg;
};

int main()
{
    std::cout << Sum(10.2f, Callback<float>) << std::endl;
    std::cout << Sum(10.2f, Callback2) << std::endl;
    std::cout << Sum(10.2f, [](auto arg) {
        std::cout << "An in-place generic lambda is called" << std::endl;
        return arg;
    }) << std::endl;

    getchar();
    return 0;
}
oblitum
  • 11,380
  • 6
  • 54
  • 120
3
#include <functional>
#include <iostream>

template<typename T>
T Sum(T _arg, std::function<T(T)> callbackFunction) // Note the std::function replacement and how callbackFunction is called below
{
    T result = callbackFunction(_arg);
    return result;
}

template<typename T>
T Callback(T _arg)
{
    std::cout << "Callback is called" << std::endl;
    return _arg;
}

int main()
{
    std::cout << Sum(10.2f, Callback);

    getchar();
    return 0;
}

This should work. This code is standard C++11, you should enable it in your compilation command.

diegoperini
  • 1,796
  • 21
  • 37
  • You should explain what you changed, and why. Not just dump code. – Lightness Races in Orbit Feb 28 '15 at 18:34
  • 2
    Don't use `std::function* type related to template parameter */>` as a parameter to function template. Generalize the argument `callbackFunction` to any type, like `T Sum(T _arg, U callbackFunction)`, [for reasons described here](http://stackoverflow.com/questions/11628765/why-do-lambda-functions-in-c11-not-have-function-types/11629125#11629125). Right now your code doesn't even compile. – milleniumbug Feb 28 '15 at 18:37
  • The change is 'callbackFunction(_arg)' instead of '(*callbackFunction)(_arg)'. – Maged Elghareib Feb 28 '15 at 18:53
  • Since we are not provided a domain or context about the problem op needs to solve, I assumed our callback has to have a strict signature as provided in the code. The changes are marked by comments now. – diegoperini Feb 28 '15 at 19:01