+10  A: 
  1. 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.
  2. insert must be used like this: mapVar.insert(make_pair(key, value)); See also cppreference.com.
  3. 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.
gimpf
As for your edit, I don't see it very clear. Imagine that the shapes grow to seven: Circle, Rectangle, Triangle, Egg, whatever. Then you have a class Piece which has a "shape" variable and want to access the assotiated value. A map will be faster.
Daniel Daranas
To Daniel: As parent mentioned, a map will be slower as it's O(logn) vs the vector's constant time.
Yes but maybe I'm missing something. The whole point in a map is that you have a key and search for _its_ assotiated value! I know the key Circle and want to access "Circle" in the map, I can't do that with a vector. I can have a vector _of_ the keys and another one _of_ the values, but not lookup.
Daniel Daranas
To Daniel -- You can index the vector<string> like so: vec[Triangle] since enums are convertible to integers.
An enum is an integer beneath, so you can use it as index (=key) for a vector, without any searching at all. This would not work with other key-types, and it only works reasonable well (wrt space) if the enum-values are sequential (and not values for a bit-map, like 2/4/8/16/etc.).
gimpf
Interesting trick. I hadn't thought of taking advantage of the default conversion and the default values of enum keys starting at 0.
Daniel Daranas
+3  A: 

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.

Aaron
Since enums are ints, do you really need to provide an ordering? I don't think so.
Konrad Rudolph
You can't have a vector<Shape, string>. You can have a vector<Shape> and a vector<string>. For key-value lookup, you _need_ a map.
Daniel Daranas
@Daniel -- vector<string> _is_ an associative data structure. it maps sequential unsigned integers to values. enums are unsigned integers, and are sequential by default. see comments on gimpf's answer.
Aaron
@Aaron, I have read them and I agree with them. Here I was refering to the fact that this answer, in line 3, mentions a "vector<Shape, string>".
Daniel Daranas
@Daniel: oops, how'd that get there? thinko fixed.
Aaron
+1  A: 

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!)

rstevens
+3  A: 

Insert fails because the value_type is std::pair

Alan
why was this voted down? the value type for map is std::pair.You guys are meanies!
Alan
+1 to offset the unnecessary downvote :P.
17 of 26
A: 

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];
}
Eclipse