可变参数的类型冲突

时间:2019-08-23 06:29:19

标签: c++ c++11 variadic-templates

我正在尝试编写一个通用的调用函数。

它具有以下语法:

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 *>);

编译器很乐意使用它,但我想尽可能避免这种情况。

作为奖励,如果每次索引更改时我都能以某种方式创建一个唯一的函数,那将很棒,因为这将使我拥有具有相同参数但返回类型不同的函数(据我所知这是非法的) )。

谢谢。

1 个答案:

答案 0 :(得分:2)

  

但是我想避免这种情况。

据我所知,还没有模板功能。

问题在于模板参数不是单个对象,而是一组对象,其中函数只能从该对象集中接受一个对象。

写作时

&invokeGlobalFunction<1, int>

您选择一个具有Index = 1ReturnType = int和一个空的Parameter...列表的精确函数。

建议:如果可以,请使用模板方法在模板invokeGlobalFunction()中转换struct

类似

template <int Index, typename ReturnType>
struct invokeStruct
 {
   template <typename ... Parameters>
   ReturnType operator() (Parameters ... parameters)
    {
      // ... 
    }
  };

这样,您就具有一组结构,每个结构中都包含一组operator();传递一个invokeStruct<1, int>{}作为参数,您传递了一个对象,但是在其中,您可以使用一组方法。