2016-12-12 12 views
0

は、私は(私のツールチェーンのC++ 11のサポートが不完全であるため)私は、ラムダを使用することはできません共有ポインタのソートリスト

list<shared_ptr<objects>> myObjects; 

をソートしたいクラスに

class objects { 
    public: 
    bool compareArea (const objects& obj) const { return this->area < obj.area; } 
    private: 
    double area; 
}; 

を考えます。したがって、私は次のように試しました:

using namespace placeholders; 
myObjects.sort(bind(&objects::compareArea,_1,_2)); 

この行は、クラスメンバーからではなく、別のファイルから呼び出されます。問題は、compareAreaが入力として2つのobjectsを必要とすることです。しかし、私はそれにobjectsへの2つの共有ポインタを与える。ポインターの逆参照を含む方法の簡単な方法はsort -callにありますか?私はobjects::compareArea(..)機能をそのまま残したいと思います。私はないは解決

compareAreaobjectsのないメンバー関数ではありません
bool compareArea (const shared_ptr<objects>& ptr1, const shared_ptr<objects>& ptr2) { 
    return ptr1->area > ptr2->area; 
} 

// in same source-file: 
myObjects.sort(bind(compareArea,_1,_2)); 

のこの種をしたいです。実際には<の演算子オーバーロードが私の好きな解決策になります。あなたは非常に簡単に(あなたがキャプチャを必要としない場合は特に)に直接ものを書くことができるように

+0

?それはあなたが必要とする種類の表現をサポートすることもできます。 – Angew

+1

'bool lessObject(const shared_ptr &lhs、const shared_ptr &rhs)についてはどうでしょうか?return lhs-> compareArea(* rhs); } '? – Jarod42

+0

@Angew私はあなたの質問を得ていません...私はstd :: bindを使用しています。プレースホルダは上記のコードスニペットに書かれているように '_1'と '_2'です。 – Kapa11

答えて

3

私は強くあなたがいずれかを保存することはありませんことを示唆していますコンテナ内のポインタの種類。

代わりに、必要な算術演算子と比較演算子をサポートするハンドルクラスを作成します。

それはおよそ推論する方が簡単ですコードになり:

使用している `bind`と` placeholders`
class objects { 
public: 
    objects(double w, double h) : area(w * h) {} 

    bool operator<(const objects& r) const { return this->area < r.area; } 
private: 
    double area; 
}; 


struct object_handle 
{ 
    object_handle(shared_ptr<objects> const& ptr) : ptr_(ptr) {} 

    static object_handle create(double w, double h) { return make_shared<objects>(w,h); } 

    bool operator < (object_handle const& r) const { 
     return *ptr_ < *r.ptr_; 
    } 
    shared_ptr<objects> ptr_; 
}; 


int main() { 
    std::vector<object_handle> mylist; 
    mylist.push_back(object_handle::create(10, 7)); 
    mylist.push_back(object_handle::create(2, 5)); 
    std::sort(mylist.begin(), mylist.end()); 
} 
+0

なぜポインタをコンテナに格納しないでください。多くの場合、項目の算術演算が要求されていないリストに共有ポインタを格納するだけです。これまで私がやったやり方の不利な点はどこですか? – Kapa11

+2

私たちは共有ポインタを操作するとき、ポインタ自体ではなく、ポインタが指しているものを操作したいと思っています。したがって、オブジェクトがどのように保持されているかの詳細を抽象化することは理にかなっています。次に、参照がどのように保持されているかの詳細を心配することなく、ハンドルのインタフェースを意味のある方法(ソート、+、 - 、より小さい、do_somethingなど)で話すことができます。後でハンドルの実装(つまり、unique_ptrs、または全くポインタがない)についての心配があれば、コードを変更する必要があるのは1か所だけです。 –

+0

さて、あなたは私を納得させました...私は将来それをやるつもりです。しかし、コンテナ内のポインタを逆参照したいだけで、その上で算術演算を実行したくない場合、このようなハンドルはコードを不要にします(たとえデータ構造をもっと簡単に拡張したとしても)。 – Kapa11

2

ラムダは、operator()を持つクラスのためだけ糖衣構文です:

struct Comparator 
{ 
    bool operator() (const shared_ptr<objects> &lhs, const shared_ptr<objects> &rhs) const 
    { 
    return lhs->compareArea(*rhs); 
    } 
}; 

myObjects.sort(Comparator()); 
+0

これは機能します。また、 'compareArea(..) '関数を' objects'の '>'演算子にオーバーロードすることで置き換えました。だから私はちょうど '(* ls)>(* rhs)'を返した。 – Kapa11

関連する問題