Для std:: map требуется, чтобы оператор компаратора() был const?
Следующий код не скомпилируется с XCode 4.5 clang++ при использовании libС++ в OS X 10.8:
#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;
}
Ошибка:
broken.cpp: 11: 8: примечание: функция-кандидат не является жизнеспособной: аргумент 'this'имеет тип 'const FooComparator', но метод не отмечен const bool operator() (const Foo & left, const Foo & right) {
Если отключить libС++ и построить с помощью libstdС++, тогда все будет хорошо. Очевидно, что я могу обойти это, создав FooComparator:: operator() const, но я хотел бы понять, является ли это проблемой при слишком строгом libС++ или стандарте (как С++ 03, так и С++ 11 ) на самом деле требует, чтобы оператор компаратора() был const (в этом случае тот факт, что он работает с libstdС++, является счастливой случайностью).
Ответы
Ответ 1
Ну, да: компаратор - это подобъект самой карты, так или иначе (возможно, член, обычно базовый класс некоторого внутреннего класса реализации). Если у вас есть постоянная ссылка на карту, компаратор по-прежнему должен использоваться для поиска, поэтому оператор должен быть const
.