rjc810
rjc810

Reputation: 495

c++ more than one instance of overloaded function matches argument type

I've overloaded my function contains three times

// 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(); 
}

The parameters are different in each overloaded function. Yet, from the line (contains(opmap, q_front)) I get the error: more than one instance of overloaded function "contains" matches the argument list.

For reference, opmap is of type std::unordered_map<char, op>, and q_front is a string. op in this case is just struct I created- I can post if needed, but I feel it is unnceessary in this case.

My question is why I'm getting this error, as the function call above should uniquely call the second method header: bool contains(std::unordered_map<char, op>& um, std::string& s){ because of the type of opmap matches the first parameter, and the type of q_front is string.

UPDATE:

Full error message:

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, "+");
    

Upvotes: 0

Views: 1636

Answers (1)

TonySalimi
TonySalimi

Reputation: 8427

Which overload you expect to match your call to the below line?

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

Overload 1 cannot match, because of your second argument, i.e. "+". Its type is const char[2] and cannot be matched to char.

Overload 2 and 3 cannot match, because the type of "+" has a const qualifier, but in those two overloads your string is passed as a non-const reference.

So, to fix your issue, you should either:

  • change "+" to '+' to use the first overload.
  • change std::string & to const std::string & to use overload 2.

Upvotes: 3

Related Questions