2

関数を持つクラスがあります

MyClass::doStuff(std::vector<MyCustomData*> toSort) { ...

私が呼ぶところ

std::sort(toSort.begin(), toSort.end(), MyClass::SortByZ());

myClass::SortByZ() はカスタム コンパレータです。これでうまくいきますが、次のことを達成したいと思います。

いくつかのクラスがあり、それぞれに「MyCustomData」をソートするための独自のコンパレーターファンクターが必要です。したがって、たとえば Class1... が必要です

class Class1 {
    struct SortData {
        bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
        return lhs->something1 > rhs->something1;
        }
    };
    //...many more functions/vars
}

一方、Class2 には、同じデータ型に対して異なる比較ファンクターがあります。

class Class2 {
    struct SortData {
        bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
        return lhs->something2 > rhs->something2;
        }
    };
    //...many more functions/vars
}

今、関数 MyClass::doStuff(...) を次のいずれかで呼び出せるようにしたいと思います

doStuff(myData, Class1::SortData)

また

doStuff(myData, Class2::SortData)

関数 MyClass::doStuff(...) は、それぞれのソート順を使用する必要があります。

これを行う方法がわかりませんでした。シンプルなソリューションが欲しいです (テンプレートなどをサポートする必要はありません)。必要に応じてブーストを使用したいと思いますが、ブーストを使用しないソリューションが優先されます。

達成したいことを説明できたと思いますか?助けてくれてありがとう!

4

2 に答える 2

6

doStuffテンプレートを作成する必要があります。

template <typename Comparator>
void doStuff(std::vector<MyCustomData*> toSort, Comparator compare) {
   // ...
   std::sort(toSort.begin(), toSort.end(), compare);
   // ...
}

また、参照によって最初の引数を取りたい場合もあります。そのままでは、引数のコピーをソートし、そのコピーを破棄し、呼び出し元のベクトルをそのままにします。おそらくそれはあなたが望むものですが。

于 2012-04-20T11:59:27.247 に答える
3

あらゆる種類の比較関数 (またはファンクター) を受け入れるために、関数テンプレートを使用します。

template <typename Comparator>
void doStuff(std::vector<MyCustomData> toSort, Comparator comparator)
{
    ...
    std::sort(toSort.begin(), toSort.end(), comparator);
    ...
}
...
doStuff(myData, Class1::SortData());
doStuff(myData, Class2::SortData());

これが、標準アルゴリズムが汎用性を提供する方法です。

于 2012-04-20T12:00:43.353 に答える