std :: map非const仿函数,在clang ++下编译时错误,对于g ++是ok

vso*_*tco 5 c++ stl functor c++11

我很好奇,如果有人知道为什么g++编译下面的代码,但clang++会出错.该代码std::map<int, int, SortCriterion>使用自定义排序仿函数创建一个SortCriterion.可以通过构造函数指定SortCriterion排序类型:升序或降序.关键比较是通过实现的operator()(int, int).一切都编译并运行正常g++,即使有-Wall, -Wextra, Wpedantic等等.但是,clang++在调用insert函数时吐出错误,并抱怨const比较运算符的-ness,即想要operator()(int, int) const.

note: candidate function not viable: 'this' argument has type
      'const SortCriterion', but method is not marked const
    bool operator()(int x, int y) //const
Run Code Online (Sandbox Code Playgroud)

现在我知道关联容器中的键不应该被搞乱,因为它会损坏容器的内部结构,但是constSTL强制执行了吗?似乎是clang++期望std::map<key, value, const comparator>,而g++不是强加const.

PS : g++4.9,Apple LLVM version 5.1 (clang-503.0.40)

#include <map>
#include <string>
#include <iostream>

using namespace std;

class SortCriterion
{
    bool ascending;
public:
    SortCriterion(bool sorting_type): ascending(sorting_type){};
    // if operator below is not marked const, 
    // clang++ spits a compile-time error on insert
    // however g++ compiles it ok
    bool operator()(int x, int y) //const
    {
        if(ascending) // ascending
            return x<y;
        else
            return x>y;
    }
};

int main()
{
    map<int, string, SortCriterion> m(SortCriterion(false)); // ascending

    m.insert({1,"one element"}); // clang++ compile error here
    m.insert({2,"another element"});
    for(auto elem: m)
        cout << elem.first << ": " << elem.second << endl;
}
Run Code Online (Sandbox Code Playgroud)

Ton*_*roy 4

C++11 标准记录了以下成员std::map

class value_compare {
    friend class map;
protected:
    Compare comp;
    value_compare(Compare c) : comp(c) {}
public:
    typedef bool result_type;
    typedef value_type first_argument_type;
    typedef value_type second_argument_type;
    bool operator()(const value_type& x, const value_type& y) const {
        return comp(x.first, y.first);
    }
};
Run Code Online (Sandbox Code Playgroud)

...鉴于value_compare::operator()const,它无法const在 上呼叫非会员comp。这意味着这部分 APICompare绝对必须有一个const operator()可用。