I was surprised when the declaration:
const std::map<double, Foo*> myCollection;
would not allow me to call non-const methods on Foo*. I thought the const applied to the collection itself (i.e., no items could be added or removed). I would think the way to convey item const would be:
std::map<double, Foo const*> myCollection;
It seems the const in the first code snippet is distributive to the contents of the map instead of my assumption of applying only to the collection.
Am I missing something here? It seems counter-intuitive. How can I call non-const methods on the Foo* objects in the fir开发者_如何学JAVAst declaration?
You must be doing something wrong -- operator[]
on std::map
is not declared const
, so it cannot be used to access elements of the map. The reason it's not const
is because if the key isn't present in the map, it gets added to the map with a default-constructed value, and doing so modifies the map.
Instead, use the find
method to get an iterator. The returned iterator cannot be used to modify the map, but it can be used to modify the objects which are pointed to by the values. For example, the following code compiles and outputs 4
:
#include <iostream>
#include <map>
typedef std::map<int, int*> Map;
void foo(const Map& m)
{
Map::const_iterator i = m.find(0);
(*i->second)++;
}
int main(void)
{
Map x;
int y = 3;
x[0] = &y;
foo(x);
std::cout << *x[0] << std::endl;
return 0;
}
Your std::map
is declared as const
. You are likely only to get const iterators
out of it.
You also can't use []
on a std::map
because that returns a reference to the map element, which means you could modify it - thus it is a compiler error.
To add to your question though, std::map
constifies its key type anyway: std::map<double, Foo*>::value_type
is std::pair<const double, Foo*>
. If you add a const
to the key type, const const double
will simply collapse to const double
.
精彩评论