2011-07-22 12 views
3

C++では、カスタム関数を定義することで、要素を並べ替える方法がわかりません。 - 最初の引数 が、秒未満である場合はtrueを返す比較関数1つの小節で要素を並べ替える方法

COMP:

Cppreference.comは、比較関数のことを言います。

ブールCMP(constのタイプ1 &、constのタイプ2 & B);

当然のことながら、私は要素をソートするために、私はメジャーを定義する必要があると思うだろう、とソート機能が依存し、それらを並べ替えます措置について

私の実際の例では、カメラからの距離によってイメージファイルをソートしたいと思います。私は、画像シーケンス

vector<boost::filesystem::path> path_vec 

のディレクトリにリンクするファイルシステム::パス::ブーストのベクトルを持っていると私は当然、私はダブルを返すだろうか

double z_distance(boost::filesystem::path filename, integer time) 

のような関数を記述する必要があると思うだろうすべての要素に対して、すべてのフレームの昇順または降順でソートします(したがって、引数の変更時間)。

ソート関数に必要なブール関数に、単一の値を返すこの関数をどのようにするべきか教えてください。

私は関数名を渡すことができますが、関数への完全な呼び出しではない場合、どのように引数を渡すことができますか?

答えて

2

そのあなたができる多くの方法があります。これを行う。

z_distanceの第2引数が常に固定値になることが分かった場合は、実際に比較を行う補助関数を記述することで関数をコンパレータに変換できます。たとえば:

bool CompareByDistance(const boost::filesystem::path& lhs, 
         const boost::filesystem::path& rhs) { 
    return z_distance(lhs, kSecondArg) < z_distance(rhs, kSecondArg); 
} 

あなたがいないがz_distance関数の2番目のパラメータがどうあるべきかを知って場合、またはそれが唯一の実行時に決定することができ、あなたは関数オブジェクトを使用する必要があります。関数オブジェクト(ファンクタと呼ばれることもあります)は、通常の関数を模倣するオブジェクトです。いくつかのパラメータを渡すことで呼び出すことができますが、それはオブジェクトなので、呼び出される関数はパラメータに加えてローカルの状態にもアクセスできます。あなたが構築することができそのような機能の1つのオブジェクトは、次のようになります。あなたには、いくつかの時間tにすべてを並べ替えたい場合

class CompareByDistance { 
public: 
    /* Constructor takes in the time that you want to sort at, 
    * then stores it for later. 
    */ 
    CompareByDistance(int time) : mTime(time) { 

    } 

    /* This is the function call operator that is called when you try 
    * treating a CompareByDistance object as a function. Note how it 
    * uses the mTime field as a parameter to `z_distance`. 
    */ 
    bool operator()(const boost::filesystem::path& lhs, 
        const boost::filesystem::path& rhs) const { 
     return z_distance(lhs, mTime) < z_distance(rhs, mTime); 
    } 
private: 
    const int mTime; // Store mTime for later 
}; 

さて、あなたはファンクタ詳細について

sort(elems.begin(), elems.end(), CompareByDistance(t)); 

を書き、などでした私が1年前に教えたC++コースのために書きましたa chapter on functorsです。

希望すると便利です。

1

さて、あなたは混乱しているところです...

関数は、結果に基づいて、内部コンテナ(木または何でも)を再調整、一度に2つの要素を比較します。だから、C++はSTL関数で知る必要があるのはあなたの関数に基づいた要素Bより小さいelmementです。

あなたの気になるように、あなたの比較機能は距離、名人、またはあなたが望むものを比較することができます。この関数は、ある要素が他の要素よりも小さい場合にtrueを返し、C++はそれをどのようにソートするかを処理します。

+0

PS:この関数は一度にあなたのSTLコンテナ、2 elemetnsの内容全体にわたり多数回実行されます - 申し訳ありませんが、私はその記事の中で述べている必要があります。だからこそ、二重に返す必要はないし、ブールで十分です。 –

3

あなたは

bool nearer(const boost::filesystem::path& a, const boost::filesystem::path& b) 
{ 
    int somevalue = 0; 
    return z_distance(a, somevalue) < z_distance(b, somevalue); 
} 

を定義するときは、

std::sort(path_vec.begin(), path_vec.end(), nearer); 

を行うことができますしかし、私はあなたの関数z_distance()の第二引数に何をするか分かりません。たぶんあなたのファイルから取得することができますか、または関数の代わりにファンクタを使用して比較する必要があります。 functorについては@templatetypedefが与えた答えを見てください。

あなたはVC++ 10をタグ付けするので、あなたはまた、C++ 0xの機能を使用することができます。引数を渡すためにラムダ式(アドホック機能を)書く:

int somevalue = 0; 
std::sort(path_vec.begin(), path_vec.end(), 
    [=](const boost::filesystem::path& a, const boost::filesystem::path& b) -> bool 
    { 
    return z_distance(a, somevalue) < z_distance(b, somevalue); 
    } 
); 
+1

コピーオペレータは 'TYPE'ではなく' const TYPE& 'を使うことをお勧めします。そうしないと、たくさん呼び出されます。そう 'BOOL近い(CONSTブースト::ファイルシステム::パスと、CONST booost ::ファイルシステム::パス&B)... ' 又はラムダ場合、 ' [=](CONSTブースト:: filesystem :: path&a、const booost :: filesystem :: path&b)... ' – Soren

+0

@Soren:私は同意し、コードを変更しました。私は書く時に少し怠け者であり、コンセプトを示すときにあまりにも多くを詰めたくはありませんでした。 –

2

過負荷operator<は、)終了()と他には何を< & B &を戻すと、ソートだけ(開始で動作するはずです。

ので

bool operator<(const SomeType& a, const SomeType& b) 
{ 
    return z_distance(a, 0) < z_distance(b, 0); 
} 

そして、あなたはこのようにそれを呼び出すことができるはずです。

std::vector<SomeType> vec; 
std::sort(vec.begin(), vec.end()); 
関連する問題