没有函数模板的实例匹配参数列表,参数类型是:(std::string, CommandLineArgumentTypes)

No instance of function template matches the argument list, argument types are: (std::string, CommandLineArgumentTypes)

我有一个函数模板,它采用 std::stringenum 值来描述字符串中包含的数据类型。它将字符串转换为 returns std::stringintunsigned intbool,具体取决于 enum 值。

template <typename T> T parseInput(std::string &input, CommandLineArgumentTypes &type) {
    switch (type) {
        case CommandLineArgumentTypes::String :
            return input;
        case CommandLineArgumentTypes::Int :
            if (int value = std::stoi(input)) {
                return value;
            }

            if (input.size() > 1) {
                if (input[0] == "0" && input[1] == "x") {
                    if (int value = std::stoi(input.substr(1, input.size() - 2))) {
                        return value;
                    }
                }
            }

            return NULL;
        case CommandLineArgumentTypes::UInt :
            return (unsigned int)std::stoi(input);
        case CommandLineArgumentTypes::Flag :
            return true;
    }
}

当我调用函数模板时

parseInput(arg, type);

其中 arg 是一个字符串,typeCommandLineArgumentTypes,我得到错误

no instance of function template matches the argument list, argument types are: (std::string, CommandLineArgumentTypes).

如何获取模板来确定 return 类型,当参数与参数列表匹配时为什么会出现此错误,更好的方法是什么?

我看到两个问题:

  1. 模板参数 T 无法从参数类型(inputtype)中推断出来。

我知道您的意图是从类型的 中推导出它,但这在 C++ 中根本不起作用。

你必须明确它,调用函数;举个例子

 parseInput<bool>(arg, type);
  1. 您的函数有不同的 return 类型。而且他们是不相容的。

C++17之前(if constexpr之前)这是做不到的。

在 C++17 中,它可以完成(使用 if constexpr,而不是 switch),但前提是测试基于编译时已知值。

因此,如果您将 type 作为模板参数传递(显然,如果您在编译时知道它的值),您可以编写一些内容(注意:代码未测试)

template <CommandLineArgumentTypes type>
auto parseInput (std::string &input)
 {
   if constexpr ( CommandLineArgumentTypes::String == type )
       return input;
   else if constexpr ( CommandLineArgumentTypes::Int == type )
    {
      // do something else
    }
   else if constexpr ( CommandLineArgumentTypes::UInt == type )
      return (unsigned int)std::stoi(input);
   else if constexpr ( CommandLineArgumentTypes::Flag == type )
      return true;
   // else ?
}

调用变成,例如,

 parseInput<CommandLineArgumentTypes::UInt>(arg);

但是,我再说一遍,这只有在模板参数(旧的 type)是已知编译类型时才有效。