简体   繁体   中英

Type map… does not provide a call operator

Attempting to implement some overloaded operators on a class Month:

class Month
{
      int monthNumber;
      string name;
}

I was able to implement the below constructor without problems:

Month::Month(int cust_month) 
{
    monthNumber = cust_month;
    name = int_month.at(cust_month);
}

Note the use of a map (not shown) int_month where int 1-12 are mapped to corresponding month names, this works fine. But attempting to do something similar when overloading the ++ operator:

Month Month::operator++() {
    if (monthNumber == 12) {
        monthNumber = 1;
        name = "January";
    }
    else{
        ++monthNumber;
        name = int_month(monthNumber); // ERROR

    }
    return *this;
}

In the above snippet int_month is highlighted and displays the error:

Type 'map<int, std::__1::string>' (aka 'map<int, basic_string<char, char_traits<char>, allocator<char> > >') does not provide a call operator

I've read similar posts and they have all resolved some sort of programming error, but after reading them I am still not sure what this error means for my code. I am curious not only how to solve it, but why using a map to assign value by key in my constructor worked fine but the same process does not work to overload an operator.

When you read the error it tells you exactly about the problem:

Type 'map<int, std::__1::string>' (aka 'map<int, basic_string<char, char_traits<char>, allocator<char> > >') does not provide a call operator

You have a map from int to string, which does not provide a call operator. That means that there is no function std::map<...>::operator()(...) . So what you have to do is that you should go to a reference like cppreference and you will see that there is no operator() .

Further, you will see that there is a section Element Access , which gives you two functions:

  • at : access specified element with bounds checking
  • operator[] : access or insert specified element

This tells you quite precisely which functions exist. If you check those in more details, you will also see the function signature , like for operator[] :

T& operator[]( const Key& key );
T& operator[]( Key&& key );

This means that you can either pass an rvalue or a const reference to an lvalue to the bracket operator. Also read carefully through the documentation and the code samples in the end to realize that values are inserted into the map if they did not exist yet (in contrary to at which will throw if the element does not exist).

So finally, some usage example:

std::map<int, std::string> m;
m[3] = "a"; // inserts "a" at position 3
std::cout << m[3]; // prints "a"
m[3] = "b"; // modifies the conetent at 3 to "b"
std::cout << m[3]; // prints "b"

m.at(3) = "c"; // modifies the content at 3 to "c"
std::cout << m[3]; // prints "b"

m.at(4) = "d"; // this will throw std::out_of_range

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM