C++模板回调与函数指针

8
我想知道是否有可能实现类似这样的功能,而不会抛出错误:
#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;
}

这是我得到的内容:
cannot use function template 'T Callback(T)' as a function argument
could not deduce template argument for 'T' from 'float'

你能否发布一个 MCVE?它可以在GCC、Clang和VS2013中编译。 - user3920237
1
这是一个最小完整可复现的程序!上述代码已足够,并且对我来说运行得非常好。 - Telokis
如果它“正常”工作,那么它就不会复制问题(即OP遇到的错误)。 - user3920237
1
传递一个调用Callback的函数对象或者执行Sum(10.2f, Callback<float>); - David G
0x499602D2 好的,看来你解决了它 :) 干杯,伙计。 - user2946316
显示剩余4条评论
2个回答

6

您不能将函数模板作为参数传递,必须传递一个实例化对象,以下是一个示例:

在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;
}

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;
}

这应该可以工作。这段代码是标准的C++11,您需要在编译命令中启用它。

你应该解释你做了什么改动,以及为什么这样做。不要只是简单地把代码丢给别人。 - Lightness Races in Orbit
2
不要将 std::function</*与模板参数相关的类型*/> 用作函数模板的参数。将参数 callbackFunction 泛化为任何类型,例如 T Sum(T _arg, U callbackFunction)原因在此。现在你的代码甚至无法编译。 - milleniumbug
改动是将 '(*callbackFunction)(_arg)' 改为 'callbackFunction(_arg)'。 - Maged Elghareib
由于我们没有提供关于问题操作需要解决的域或上下文,我假设我们的回调必须具有代码中提供的严格签名。现在通过注释标记更改。 - diegoperini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接