- Having an enum as key_type is not bad by itself. (edit) But if you only use sequential enum-values, a
std::vector
with O(1) access is even better. insert
must be used like this:mapVar.insert(make_pair(key, value));
See also cppreference.com.- Yes,
std::map
has O(log(n)) lookup, as guaranteed by the standard, and this is much faster as O(n) if n is sufficiently high.
1) Is keeping an enum as key in std::map a good practice?
Well, for efficiency, with such a small enum, you'd be better off with a vector or tr1::array of either values (if your value type supports 'empty' values) or smart pointers. ex: vector<string>
For correctness -- I believe you're fine. Map can work with any key type that is sortable -- that is, that have operator<, or for which you provide a sorting function. Enums have ordering by default
2) In strMap.insert(Shape::Circle,"Circle")
why insert method is [giving] a compiler error?
Because insert doesn't take two values. it takes a pair. try:
#include <utility>
...
strMap.insert(make_pair(Circle, string("Circle")));
3) When find() method is used in the map class, [it's] doing some logarithmic search ... correct?
Yes. map::find is O(lg(map::size())) time. map stores its key-value pairs in a data structure sorted by key. insert and erase are O(lg(n)), as is find. It also provides bidirectional iterators, meaning that you can find the next or previous item in the map in O(1) constant time, but you cannot skip forward and backward more than one element at a time.
Edit: corrected that enums have ordering by default.
Try using
strMap.insert(std::pair<Shape, std::string>(Circle,"Circle"));
instead (not Shape::Circle!).
Enum values are visible at the same scope as the enum is in C++ (very ugly and I absolutely don't like it but that's how it is!)
For situations like this, where you often just want a static mapping of enums to strings, it's often easier to do something like this:
enum Shape{
Circle,
Rectangle,
NShapes,
};
char *ShapeNames[] =
{
"Circle",
"Rectangle",
};
void CheckShapeNames()
{
// Use a static_assert here instead if you have it in your library
int ShapeNamesCount[(sizeof(ShapeNames)/sizeof(char*)) == NShapes];
}
From then on, accessing the shape names is simple a matter of accessing the ShapeNames array:
string name = ShapeNames[Shape::Circle];
or even:
for (int i=0; i < Shape::NShapes; ++i)
{
cout << ShapeNames[i];
}