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

时间:2014-07-29 01:09:29

标签: c++ c++11 stl functor

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

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

PS:g++4.9Apple 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;
}

1 个答案:

答案 0 :(得分:4)

C ++ 11 Standard标记了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);
    }
};

...鉴于value_compare::operator()const,它无法呼叫const上的非comp成员。这意味着Compare绝对必须有const operator()才能使这部分API可用。