適切な比較関数を動的に作成するコードを提供するように求められたため...
std::stable_sort
免責事項: 次のコードは、安定した並べ替えアルゴリズムを使用してベクトルを複数回並べ替えることと、パフォーマンスの点ではおそらく比較できません。アイデアを説明するためだけのものです。次のコードはC++11
、まだ利用できない機能を使用して記述されています。C++03
ただし、たとえば、を使用して簡単に書き換えることができますboost
。
A
クラスと、メンバー変数ごとにいくつかのゲッター関数があると仮定しましょう。
class A
{
public:
float getA() const;
int getB() const;
// and so on.
};
-1
の 1 つのインスタンスがA
他のインスタンスよりも小さい場合は 、0
等しい場合は 、そうでない場合は を返す関数を定義します1
。これらの機能は、より簡単に組み合わせることができます。
using comparator = std::function<int (const A&, const A&)>;
template <class T>
comparator
make_comparator( T (A::*f)() const )
{
return [f]( const A& lhs, const A& rhs ) -> int {
if( (lhs.*f)() < (rhs.*f)() )
return -1;
else if( (lhs.*f)() == (rhs.*f)() )
return 0;
else
return 1;
};
}
ここで、メンバー関数ごとに を定義していcomparator
ます:
std::vector<comparator> comparators = {
make_comperator( &A::getA ), make_comparator( &A::getB )
};
比較機能を簡単に組み合わせることができます。
comparator
make_comparator(
const std::vector<comparator> &comparators,
std::deque<unsigned int> indices )
{
if( indices.empty() )
{
return []( const A&, const A& ) -> int { return 0; };
}
unsigned int first = indices.front();
indices.pop_front();
return [first, &comparators, indices]( const A& lhs, const A& rhs ) -> int {
int firstCompared = comparators[first]( lhs, rhs );
if( firstCompared != 0 )
{
return firstCompared;
}
else
{
return make_comparator( comparators, indices )( lhs, rhs );
}
};
}
less
これらの関数は、のようなファンクターに変換できます。
std::function<bool (const A&, const A&)>
to_less( std::function<int( const A&, const A& )> f )
{
return [&f]( const A& lhs, const A& rhs ) -> bool {
return f( lhs, rhs ) < 0;
};
}
2 番目の列よりも 1 番目の後の並べ替え:
std::sort( instances.begin(), instances.end(),
to_less( make_comparator( comparators, { 0, 1 } ) ) );