0

Ok here is the code snippet that I am having the problem with (class name has been changed due to work reason)

const std::map<A*, std::pair<int, B*> > &aMap = ot->getAMap();
A *a = getAFromSomewhere();
B* b = aMap[a].second; //The line that the compilation error points to.

Error: The operation "const std::map<A*, std::pair<int, B*>, std::less<A*>, std::allocator<std::pair<A*const, std::pair<int, B*>>>>[A*]" is illegal.

anyone has any idea why this is so?

20
  • 1
    It is so because it is not valid C++. B* is not valid C++. Commented Nov 17, 2016 at 1:36
  • Sorry I do not get it why do you say it is not valid. Commented Nov 17, 2016 at 1:37
  • aMap[a] should return the pair, and .second should access the B* Commented Nov 17, 2016 at 1:38
  • 1
    Because it is not. It is not valid according to the specification for the C++ language. Commented Nov 17, 2016 at 1:38
  • 1
    Right. And that's not valid C++. If it were, you would not get the compilation error. Commented Nov 17, 2016 at 1:40

2 Answers 2

2

The subscript operator for the class std::map is declared like

T& operator[](const key_type& x);
T& operator[](key_type&& x);

As you can see it is declared for non-constant objects of the class because if there is no object in the map with the given key then it is created by the operator.

And your object is constant due to the constant reference

const std::map<A*, std::pair<int, B*> > &aMap = ot->getAMap();
^^^^^

You should use member function at that is declared for constant objects.

const T& at(const key_type& x) const;
                               ^^^^^

If you have an old compiler that does not support C++ 2011 then you can use member function find.

Sign up to request clarification or add additional context in comments.

4 Comments

unfortunately, I cant use at() because the compiler I have here is older than that. so only C++98 is available for me
@Mox See my updated post.
thanks for the update, that also answered my question on why my colleague used find in the code. =)
@Mox Maybe he already asked a similar question at SO, did not he?:)
1

aMap is const, but std::map::operator[] is non-const member function (overloads), which can't be called on const object.

Use it with a non-const object will work, e.g.

std::map<A*, std::pair<int, B*> > aMap = ot->getAMap(); // aMap is non-const, copied from the returned map
A *a = getAFromSomewhere();
B *b = aMap[a].second;

5 Comments

but the get getAMap() return a const std::map<A*, std::pair<int, B*> > & type. so shouldnt my aMap be const too?
@Mox Then you can't call operator[] on the returned map directly. You can make a copy then call operator[] on it like my sample showed, or use at() as @ladfromMoscow answered; but note its behavior is not same as operator[]. It depends on your needs, if you don't want to insert value if key doesn't exist, then you should use at() instead of operator[].
I will give your solution a shot =)
sorry to bother you again, just a quick question related to your solution and vlad's. while urs creates a new copy (I assume) but with a O( log N) complexity to find the object, and Vlad's has an O(N) run time for find, which is more recommended ?
@Mox If you just want to get the element from map, you should use std::map::find(), it's O(log N) too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.