我正在尝试编写一个通用的调用函数。
它具有以下语法:
template<int Index, typename ReturnType, typename... Parameter>
ReturnType invokeGlobalFunction(Parameter... parameters)
{
return invocator->invoke<ReturnType>(Index, parameters...);
}
接下来,我尝试从中派生两个不同的功能点,像这样:
registerFunction(::someGlobalFunction, &invokeGlobalFunction<0, void>);
registerFunction(::someOtherFunction, &invokeGlobalFunction<1, int>);
someGlobalFunction
具有原型void someGlobalFunction()
,而someOtherFunction
具有原型int someOtherFunction(int, const char *)
。
在第一个调用中,它就像一个超级按钮一样工作,但是第二个调用抛出错误:candidate template ignored: deduced conflicting types for parameter 'Parameter' (<int, const char *> vs. <>)
。
这意味着,编译器(在Ubuntu系统上为g ++ 7.4.0 btw。)不会像我期望的那样用不同的参数集重载invokeGlobalFunction
。
注意:当我在调用中明确设置参数类型
registerFunction(::someOtherFunction, &invokeGlobalFunction<1, int, int, const char *>);
编译器很乐意使用它,但我想尽可能避免这种情况。
作为奖励,如果每次索引更改时我都能以某种方式创建一个唯一的函数,那将很棒,因为这将使我拥有具有相同参数但返回类型不同的函数(据我所知这是非法的) )。
谢谢。
答案 0 :(得分:2)
但是我想避免这种情况。
据我所知,还没有模板功能。
问题在于模板参数不是单个对象,而是一组对象,其中函数只能从该对象集中接受一个对象。
写作时
&invokeGlobalFunction<1, int>
您选择一个具有Index = 1
,ReturnType = int
和一个空的Parameter...
列表的精确函数。
建议:如果可以,请使用模板方法在模板invokeGlobalFunction()
中转换struct
。
类似
template <int Index, typename ReturnType>
struct invokeStruct
{
template <typename ... Parameters>
ReturnType operator() (Parameters ... parameters)
{
// ...
}
};
这样,您就具有一组结构,每个结构中都包含一组operator()
;传递一个invokeStruct<1, int>{}
作为参数,您传递了一个对象,但是在其中,您可以使用一组方法。