1

単純に見える問題がありますが、それに対するエレガントな解決策を見つけることができません。

2回ソートする必要があるリンクリストを使用しています。

  • リスト要素が追加されるときに1つのパラメータに1回、および
  • いくつかの処理の後、別のパラメータで1回。

リストに格納するオブジェクトは、抽象リストアイテムの基本クラスから継承します。

問題は、2番目のパラメーターに頼ることにあります。後でリストアイテムの基本クラスから継承する他のオブジェクトをリストに格納するため、リストアイテムの基本クラスに純粋な仮想アクセサーを記述したくありませんが、2番目のアクセサーは彼ら。

私が見逃しているクリーンな解決策はありますか?

4

3 に答える 3

3

述語を使用します。

std::list<Base*> myList; /* populate */

myList.sort([](Base * const p1, Base * const p2) -> bool
            { return static_cast<Derived*>(p1)->compare_with(*p2); }
           );

これは、並べ替えの実行中に、すべての要素が実際には bool を返すDerivedメンバー関数foo(仮想である必要さえありません) を持つポインターであると想定しています。

もちろん、述語の詳細は好きなように変更できます。古いコンパイラを使用している場合は、ラムダ式を従来のスペルアウトされた述語クラスに置き換えることもできます。

Derivedすべての要素が実際に型であると確信できない場合は、dynamic_cast代わりに a を使用できますが、比較できないすべてのオブジェクトを並べ替える方法を考える必要があります。その場合、最初に範囲をあるものとそうでないものに分割しDerived、前者のみをソートすることをお勧めします。

于 2012-06-11T17:05:35.083 に答える
1

私が正しく理解していれば、あなたはそのようなものを持っています:

 class Base {
    public:
    int getParam1() const { ... }; 
    virtual void foo() =0;  // this is an abstract class
    virtual ~Base() { ... }
 }
 class Derived : public Base {
    public:
    int getParam1() const { ... }
    int getParam2() const { ... }

 }

そして、あなたはstd::list<Base*> myListどこかにいます。初めてリストを並べ替えるときは、次のようにします。

sort(list.begin(),list.end(),[](const Base*v1,const Base*v2) {
    return v1->getParam1()<v2->getParam1();
});

また、2番目の並べ替えでは、クラスに固有の何かを使用する必要がありますDerivedgetParam2()純粋な仮想アクセサーをに追加してBase実装する必要はありませんDerived。ただし、リストに派生オブジェクトのみが含まれていることがわかっている場合は、キャストを問題なく使用できます。

sort(list.begin(),list.end(),[](const Base*b1,const Base*b2) {
    const Derived * d1 = dynamic_cast<const Derived*>(b1);
    const Derived * d2 = dynamic_cast<const Derived*>(b2);

    return d1->getParam2() < d2->getParam2();
});

リストのオブジェクトが、でない場合はDerived、dynamic_castが返さnullptrれるため、安全に確認できます。

于 2012-06-11T17:09:21.360 に答える
0

これらの要素を比較する方法のさまざまなバージョンについて、(独自の設計の)コンテナーの要素を並べ替えたいことを正しく理解していますか?その場合は、ソートアルゴリズムに比較ファンクター/関数を提供するだけです。

于 2012-06-11T17:09:00.457 に答える