How do I fix this error message error: no match for ‘operator[]’

113 Views Asked by At

I am implementing a class that involves unordered_sets, and unordered_maps. When I go to run the program it gives me the following error

error: no match for ‘operator[]’ (operand types are ‘std::unordered_set<std::__cxx11::basic_string<char> >’ and ‘const string’ {aka ‘const std::__cxx11::basic_string<char>’})
     int points = Prizes[Codes[code]]->points;

I am unsure of how to fix this, please help.

I have pasted my function (sightly condensed) below.

int Code_Processor::Enter_Code(const string &username, const string &code) {
    User *user = user_iter->second;
    int points = Prizes[Codes[code]]->points;
    user->points += points;
    Codes.erase(code);
    return points;
}

I have also included part of the header file below.

class User {
  public:
     std::string username;
     std::string realname;
     int points;
     std::set <std::string> phone_numbers;
};

class Prize {
  public:
     std::string id;
     std::string description;
     int points;
     int quantity;
};

class Code_Processor {
  public:
    int Enter_Code(const std::string &username, const std::string &code);

  protected:
    std::unordered_map <std::string, User *> Names;
    std::unordered_map <std::string, User *> Phones;
    std::unordered_set <std::string> Codes;
    std::unordered_map <std::string, Prize *> Prizes;
};
2

There are 2 best solutions below

0
Vlad from Moscow On BEST ANSWER

The class template std::unordered_set does not have the subscript operator.

You could write for example

if ( Codes.find( code ) != Codes.end() )
{
    int points = Prizes[code]->points;
    user->points += points;
    Codes.erase(code);
}
0
Dima On

std::unordered_set doesn't support the indexing operator as there would be nothing to return because it only stores keys and no values.

If you're trying to check that the value is present in the set, you can do it like this:

if (Codes.find(code) != Codes.end()) {
  // Do stuff
}

Alternatively, if you have a compiler that supports C++ 20, you can write it like this.

if (Codes.contains(code)) {
  // Do stuff
}

I should also note that not checking if a key is present in the map before trying to access it the way you do may lead to undefined behavior and crashes due to null pointer dereferencing, as the map would create a default value for a new key which in case of a pointer would be nullptr.

You can read more about standard associative containers here.