2017-08-27 11 views
0

std :: sortとstd :: stable_sortの修飾子のoperator<constの要件の違いについてちょっと混乱します。私たちはこのコードをコンパイルして実行しようとした場合オペレータの要件<std :: stable_sortのconstness

#include <vector> 
#include <algorithm> 

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

すべてはokです:シンプルな構造とし

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; } 

だから私の質問は: それは技術的な実装の詳細の結果に過ぎないのでしょうか、そうした行動に有利ないくつかの客観的な議論がありますか?

+0

あなたが表示するコードのどれも 'std :: stable_sort'を呼び出すことはありません。エラーは必ず表示していないコードを参照します。 –

+0

場合によっては、すべての要件を満たしていないことがあります。ソートアルゴリズムは、const値を比較に渡すことはできますが、必須ではありません。そしてBTWは、常に「真」を返すことは別の違反です。 'a

+0

@BoPersson - 私は 'return true;'が** example **をより単純にすることを前提としていました。問題は実行時ではなくコンパイル時に発生します。 –

答えて

0

[alg.sorting]/2Compare機能オブジェクトタイプ(20.9)です。文脈的にbool(項4)に変換されたとき、タイプCompareのオブジェクトに適用された関数呼び出し操作の戻り値は、呼び出しの最初の引数がfalse以外の場合はtrueとなります。 Compare compは、順序関係を仮定してアルゴリズム全体で使用されます。 compは逆参照されたイテレータを介して非定数関数を適用しないものとします。 Compareを取るすべてのアルゴリズムについて

[alg.sorting]/3、代わりoperator<を使用するバージョンがあります。つまり、comp(*i, *j) != falseのデフォルトは*i < *j != falseです。特定の場合において

[res.on.functions]/1(置換関数、ハンドラ関数、標準ライブラリテンプレートコンポーネントをインスタンス化するために使用するタイプの操作)、C++標準ライブラリは、C++プログラムによって供給された構成要素に依存します。これらのコンポーネントが要件を満たしていない場合、この標準は実装上の要件を置かない。

強調鉱山。プログラムは、関数の要件を満たしていないコンポーネントを標準ライブラリ関数に供給することによって、未定義の動作を示します。

ところで、clangはstd::sortstd::stable_sortの両方を拒否します。

関連する問題