std :: map是否要求比较器的operator()为const?

acm*_*acm 14 c++ libc++

在OS X 10.8上使用libc ++时,以下代码无法使用XCode 4.5的clang ++进行编译:

#include <map>
#include <string>

class Foo {
public:
  explicit Foo(int val_) : val(val_) {}
  int val;
};

struct FooComparator {
  bool operator()(const Foo& left, const Foo& right) {
    return left.val < right.val;
  }
};

int main(int argc, char* argv[]) {

  std::map<Foo, std::string, FooComparator> m;

  Foo f(4);
  m[f] = std::string("four");

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

broken.cpp:11:8:注意:候选函数不可行:'this'参数的类型为'const FooComparator',但是方法没有标记为const bool operator()(const Foo&left,const Foo&right){

如果我关闭libc ++并使用libstdc ++构建,那么一切都很好.显然,我可以通过制作FooComparator :: operator()const来解决这个问题,但是我想知道这是否是libc ++过于严格的问题,还是标准(C++ 03和C++ 11)确实要求比较器的operator()是const(在这种情况下,它与libstdc ++一起工作的事实是一个幸福的事故).

Ker*_* SB 19

嗯,是的:比较器是地图本身的一个子对象,不管是哪种方式(可能是成员;通常是某个内部实现类的基类).如果你有一个对映射的恒定引用,比较器仍然需要可用于查找,因此运算符需要const.

  • 我知道我在挑剔,因为很明显,实际的答案是"只是让它成为常数".但是,在我看来,使用非const运算符()的比较器来实例化std :: map是合法的,只要你不以需要const的方式使用map(在这种情况下,libc ++)似乎有一个错误,它需要非const上下文中的比较器常量),或者它是不合法的,libstdc ++应该拒绝上面的代码,但不是.或者这在某种程度上属于实现定义的行为,所以两者都是正确的? (2认同)