DuckQueen
DuckQueen

Reputation: 802

why std::map<int, float> cant use operator[]: error C2678?

Having:

std::map<const int, float> m_areaCost;

I'm trying to compile the following:

inline float getAreaCost(const int i) const { 
    return m_areaCost[i]; 
}

Which leads to the following error:

error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion) 

I used to think when we call [elementId] we get element value or default element value so I wonder how can such simple case lead to compilation errors?

Upvotes: 1

Views: 3126

Answers (4)

Marson Mao
Marson Mao

Reputation: 3035

The reason is that getAreaCost being declared as const, like others has stated, but I'd like to give some more suggestions:

A function should always return a useful value, so I would suggest getAreaCost to be:

inline float getAreaCost(int i) const { 
    std::map<const int, float>::const_iterator It = m_areaCost.find(i);

    if (It != m_areaCost.end()) return It->second;

    return 0.0f;
}

Some points:
1. input parameter is pass-by-value, so no need forconst int i, just use int i.
2. if you find things like std::map<const int, float>::const_iterator is verbose, give it a typedef. (If you dont, feel free to keep write it, of course :P)
3. 0.0f is just for example, you can return any default value that is suitable in your case.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

Because you marked the method to be const.

When you do return m_areaCost[i]; you can actually create the entry in the map if the key does not exist, therefore the operation is not constant so you have a mismatch between your constant function and non-constant operator[] of the map.

If you want the member function to be const then you have to use find to find the entry for the key.

Upvotes: 0

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

Presumably m_areaCost is a member of the object that getAreaCost is a member of. However, getAreaCost is marked as a const member function. This means it can't cause any modification to members. So the m_areaCost member is const in this function.

You cannot call operator[] on a const std::map because its effect is that it inserts a new element if it does not yet exist. Instead use std::map::at:

return m_areaCost.at(i);

Upvotes: 7

Alon
Alon

Reputation: 1804

Because you state that your function is const, and the [] is not a const operator. As you said so yourself, the [] !creates or returns a new value.. if it cannot create then you cannot use this operator.. I would use find() and then return the .second value if it is there, something like:

auto it = m_areaCost.find(i);
if (it != m_areaCost.end()) return (*it).second

Upvotes: 1

Related Questions