【问题标题】:c++ more than one instance of overloaded function matches argument typec++ 多个重载函数实例匹配参数类型
【发布时间】:2021-09-28 07:59:17
【问题描述】:

我已经重载了我的函数contains 3 次

// returns true if char c is contained in unordered map um
bool contains(std::unordered_map<char, op>& um, char c){
    return um.find(c) != um.end();
}

// returns true if string s is contained in unordered map um
bool contains(std::unordered_map<char, op>& um, std::string& s){
    return s.length() == 1 && contains(um, s[0]); 
}

// returns true if string s is contained in unordered map um
bool contains(std::unordered_map<std::string, func>& um, std::string& s){
    return um.find(s) != um.end(); 
}

每个重载函数的参数都不一样。然而,从(contains(opmap, q_front)) 行我得到错误:more than one instance of overloaded function "contains" matches the argument list

作为参考,opmapstd::unordered_map&lt;char, op&gt; 类型,q_frontstringop 在这种情况下只是我创建的结构 - 如果需要我可以发布,但我觉得在这种情况下它是不必要的。

我的问题是为什么我会收到这个错误,因为上面的函数调用应该唯一地调用第二个方法头:bool contains(std::unordered_map&lt;char, op&gt;&amp; um, std::string&amp; s){ 因为opmap 的类型匹配第一个参数,而q_front 的类型是string

更新:

完整的错误信息:

more than one instance of overloaded function "contains" matches the argument list: -- function "contains(std::unordered_map<char, op, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, op>>> &um, std::string s)" (declared at line 48 of "/Users/raleighclemens/Documents/Calc_cpp/calc.h") -- function "contains(std::unordered_map<char, op, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, op>>> &um, std::string &s)" (declared at line 49) -- argument types are: (std::unordered_map<char, op, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, op>>>, std::string)C/C++(308)

MRE:

#include <iostream>
#include <string>
#include <functional>
#include <unordered_map>

#define LEFT 0
#define RIGHT 1
#define UNARY 0
#define BINARY 1

struct op{
    char symbol;
    uint8_t precedence;
    uint8_t assoc;
    uint8_t type;

    std::function<double (double, double)> ashley;

};

struct func{
    std::string symbol;
    uint8_t type;

    std::function<double (double, double)> ashley;
};

bool contains(std::unordered_map<char, op>& um, char c){
    return um.find(c) != um.end();
}

// returns true if string s is contained in unordered map um
bool contains(std::unordered_map<char, op>& um, std::string& s){
    return s.length() == 1 && contains(um, s[0]); 
}

// returns true if string s is contained in unordered map um
bool contains(std::unordered_map<std::string, func>& um, std::string& s){
    return um.find(s) != um.end(); 
}


int main(int argc, char** argv){

    std::unordered_map<char, op> opmap;
    op op1{'+', 2, LEFT, BINARY, [=] (double a, double b){return a + b;}};
    opmap.emplace('+', op1);

    std::cout << contains(opmap, "+");
    

【问题讨论】:

  • 你能提供一个minimal reproducible example 和确切的错误信息吗?
  • 您的代码包含多个可能不相关的问题,例如无缘无故使用非常量引用。此外,您未能包含整个错误消息文本;这是个坏主意。您可能不理解该错误,但该错误将描述您的问题。将其包含在引用的代码块中。第三,minimal reproducible example 非常有用,可以轻松解决您的问题。
  • 无论如何,使用const std::string&amp; s 而不是std::string&amp; s 非常重要,因为前者允许您将临时变量作为参数传递。在您的情况下,您有一个临时的,甚至不是 std::string,而是 const char[2]
  • char 数组在概念上是一个字符串,但它与实际类 std::string 之间存在许多技术差异。至于const 这件事很重要,here's 是一个很好的问题。
  • 错误信息清楚地显示了模棱两可的重载是contains(std::unordered_map&lt;char, op&gt; &amp;um, std::string s)contains(std::unordered_map&lt;char, op&gt; &amp;um, std::string &amp;s),但是在显示的代码中没有带有非引用std::string s参数的重载。

标签: c++ function methods overloading


【解决方案1】:

您希望哪个重载与您对以下行的调用相匹配?

std::cout << contains(opmap, "+");

由于您的第二个参数,即"+",重载 1 无法匹配。其类型为const char[2],无法与char匹配。

重载 2 和 3 无法匹配,因为 "+" 的类型有一个 const 限定符,但在这两个重载中,您的 string 作为非常量引用传递。

因此,要解决您的问题,您应该:

  • "+" 更改为'+' 以使用第一个重载。
  • std::string &amp; 更改为 const std::string &amp; 以使用重载 2。

【讨论】:

  • 谢谢!但是为什么"+" 隐式键入const char* 而不是std::string?还有为什么const char* 可以隐式转换为const std::string 而不是std::string
  • @rjc810 你错过了const std::string&amp;std::string&amp;,也就是说引用。
  • @rjc810 "+" 是一个字符串文字,它的类型是const char[2],在某些情况下它衰减const char*std::string 有一个接受const char* 的非explicit 构造函数,因此您可以将const char[N] 传递给(const) std::stringconst string&amp; 变量/参数,但不能传递给非常量std::string&amp; 引用.如果您希望"+" 成为字符串,请改用contains(opmap, string("+"))using std::literals::string_literals; contains(opmap, "+"s)
  • @RemyLebeau 感谢您的准确澄清;)
  • @RemyLebeau contains(opmap, string("+")) 会遇到同样的问题,您不能将prvalue 绑定到非常量引用,不是吗?您仍然需要更改函数签名,此时 "+" 本身就可以工作。
猜你喜欢
  • 2012-10-12
  • 1970-01-01
  • 2021-10-11
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多