【问题标题】:No instance of function template matches the argument list, argument types are: (std::string, CommandLineArgumentTypes)没有函数模板的实例与参数列表匹配,参数类型为:(std::string, CommandLineArgumentTypes)
【发布时间】:2020-08-01 15:04:08
【问题描述】:

我有一个函数模板,它接受一个std::string 和一个enum 值,用于描述字符串中包含的数据类型。它将字符串转换为并返回 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).

如何让模板确定返回类型,为什么当参数与参数列表匹配时会出现此错误,以及有什么更好的方法?

【问题讨论】:

  • 返回类型必须在编译时知道,并且必须是固定类型。可以让函数模板以type为模板参数,然后使用if constexpr进行适当的分支。

标签: c++ templates return-type template-argument-deduction


【解决方案1】:

我看到两个问题:

  1. 模板参数T 不能从参数类型(inputtype)推导出来。

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

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

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

在 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)是已知的编译类型时才有效。

【讨论】:

  • 显式调用模板函数是我想知道的。有没有简单的方法可以根据枚举设置type
  • @TwistyTurtleFish - 不确定理解您的问题...修改了答案(在最后一个示例中)以使其更清楚一点;希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多