Следующий код не может быть скомпилирован с Clang ++ XCode 4.5 при использовании libc ++ на 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& слева, конст фу& право) {
Если я выключу libc ++ и соберусь с libstdc ++, тогда все будет хорошо. Очевидно, что я могу обойти это, сделав FooComparator :: operator () const, но я хотел бы понять, является ли это проблемой из-за слишком строгого libc ++ или стандарта (как C ++ 03, так и C ++ 11 ) фактически требует, чтобы оператор компаратора () был const (в этом случае тот факт, что он работает с libstdc ++, является счастливой случайностью).
Что ж, да: компаратор является подобъектом самой карты, так или иначе (может быть, членом; обычно это базовый класс некоторого внутреннего класса реализации). Если у вас есть постоянная ссылка на карту, компаратор все еще должен использоваться для поиска, поэтому оператор должен const
,
Других решений пока нет …