使用std :: map时这些适当的做法是什么?

时间:2009-01-28 18:23:25

标签: c++ enums map standard-library

我对使用std::map

有一些疑问
  1. 使用enum作为std::map的关键是一个好习惯吗?请考虑以下代码:

    enum Shape{
        Circle,
        Rectangle
    };
    
    int main(int argc, char* argv[])
    {
         std::map<Shape,std::string> strMap;
         // strMap.insert(Shape::Circle,"Circle"); // This will not compile
         strMap[Shape::Circle] = "Circle";         // But this will work
         return 0;
    }
    
  2. 在上面的示例中,为什么在重载insert()运算符正常工作时调用[]会产生编译器错误?建议将哪些方法插入std::map

  3. 我理解当在find()类上使用std::map方法时,它不是在容器中进行顺序搜索,而是进行一些对数搜索,这比顺序要快得多搜索。这种理解是否正确?

5 个答案:

答案 0 :(得分:12)

  1. 将enum作为key_type本身并不坏。 (编辑)但是如果您只使用顺序枚举值,那么具有O(1)访问权限的std::vector会更好。
  2. insert必须像这样使用:mapVar.insert(make_pair(key, value)); 另请参阅cppreference.com
  3. 是的,std::map有O(log(n))查找,由标准保证,如果n足够高,这比O(n)快。

答案 1 :(得分:5)

插入失败,因为value_type是std :: pair

答案 2 :(得分:3)

1)将enum作为std :: map的关键是一个好习惯吗?

嗯,为了提高效率,使用这么小的枚举,你最好使用任一值的向量或tr1 ::数组(如果你的值类型支持'空'值)或智能指针。例如:vector<string>

为了正确 - 我相信你很好。 Map可以使用任何可排序的键类型 - 即具有operator&lt;或者为其提供排序功能的键类型。枚举默认排序

2)在strMap.insert(Shape::Circle,"Circle")中为什么insert方法[给出]编译器错误?

因为insert不带两个值。需要一双。尝试:

#include <utility>
...
strMap.insert(make_pair(Circle, string("Circle")));

3)当在地图类中使用find()方法时,[它]正在做一些对数搜索...正确吗?

是。 map :: find是O(lg(map :: size()))时间。 map将其键值对存储在按键排序的数据结构中。插入和擦除是O(lg(n)),如找到的那样。它还提供双向迭代器,这意味着您可以在O(1)常量时间内找到地图中的下一个或上一个项目,但不能一次向前和向后跳过多个元素。

修改:更正了枚举默认排序。

答案 3 :(得分:1)

尝试使用

strMap.insert(std::pair<Shape, std::string>(Circle,"Circle"));

代替(不是Shape :: Circle!)。

枚举值与cum中枚举的范围相同(非常难看,我绝对不喜欢它,但它就是这样!)

答案 4 :(得分:0)

对于这样的情况,你通常只想要枚举到字符串的静态映射,通常更容易做到这样的事情:

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

从那时起,访问形状名称很简单,只需访问ShapeNames数组:

string name = ShapeNames[Shape::Circle];

甚至:

for (int i=0; i < Shape::NShapes; ++i)
{
    cout << ShapeNames[i];
}