运营商的要求< std :: stable_sort中的constness

时间:2017-08-27 12:49:52

标签: c++ stl

我对std :: sort和std :: stable_sort的operator< const限定符的要求有所不同。假设一个简单的结构:

#include <vector>
#include <algorithm>

struct Custom {
    bool operator<(const Custom& custom) /* const */{
        return true;
    };
};

如果我们尝试编译并运行此代码,一切正常:

int main() {
    std::vector<Custom> values(3);
    std::sort(values.begin(), values.end());
    return 0;
}

但是std::stable_sort的代码无法编译:

int main() {
    std::vector<Custom> values(3);
    std::sort(values.begin(), values.end());
    return 0;
}

这是一个错误堆栈跟踪:

In file included from /usr/include/c++/5/bits/stl_algobase.h:71:0,
                 from /usr/include/c++/5/bits/char_traits.h:39,
                 from /usr/include/c++/5/ios:40,
                 from /usr/include/c++/5/ostream:38,
                 from /usr/include/c++/5/iostream:39,
                 from temp.cpp:1:
/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Val_less_iter::operator()(_Value&, _Iterator) const [with _Value = const Custom; _Iterator = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >]’:
/usr/include/c++/5/bits/stl_algo.h:2050:14:   required from ‘_ForwardIterator std::__upper_bound(_ForwardIterator, _ForwardIterator, const _Tp&, _Compare) [with _ForwardIterator = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >; _Tp = Custom; _Compare = __gnu_cxx::__ops::_Val_less_iter]’
/usr/include/c++/5/bits/stl_algo.h:2522:26:   required from ‘void std::__merge_without_buffer(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Distance, _Distance, _Compare) [with _BidirectionalIterator = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >; _Distance = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/5/bits/stl_algo.h:2782:34:   required from ‘void std::__inplace_stable_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/5/bits/stl_algo.h:4863:28:   required from ‘void std::__stable_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/5/bits/stl_algo.h:4897:36:   required from ‘void std::stable_sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Custom*, std::vector<Custom> >]’
temp.cpp:15:45:   required from here
/usr/include/c++/5/bits/predefined_ops.h:71:22: error: no match for ‘operator<’ (operand types are ‘const Custom’ and ‘Custom’)
       { return __val < *__it; }

所以我的问题是: 这只是技术实施细节的结果还是存在一些支持这种行为的客观论据?

1 个答案:

答案 0 :(得分:0)

  

[alg.sorting] / 2 Compare是一个函数对象类型(20.9)。当上下文转换为Compare(第4条)时,应用于类型bool的对象的函数调用操作的返回值,如果调用的第一个参数小于true,则返回false第二个,否则Compare comp。假定有序关系的算法始终使用comp假设Compare不会通过解除引用的迭代器应用任何非常量函数。

     

[alg.sorting] / 3 对于所有采用operator<的算法,都有使用comp(*i, *j) != false的版本。也就是说,*i < *j != false默认为std::sort

     

[res.on.functions] / 1 在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C ++标准库依赖于由一个C ++程序。如果这些组件不符合要求,则标准对实施没有要求。

强调我的。您的程序通过向标准库函数提供不符合函数要求的组件来展示未定义的行为。

顺便说一句,clang拒绝std::stable_sortjsconfig.json