2012-04-05 7 views
6

私は、別のクラスのオブジェクトに対してboost::shared_ptrsを含むリストを保持するクラスを持っています。shared_ptrのコンテナですが、生ポインタを反復します

リストのelemetsにアクセスするクラスメンバー関数は、生ポインタを返します。一貫性を保つためにshared_ptrsの代わりにrawポインタを使って反復することもできます。したがって、リストイテレータを参照解除するときは、shared_ptrではなく、未処理のポインタを取得したいと考えています。

私はこれのためにカスタムイテレータを書く必要があると仮定します。これは正しいです?もしそうなら、誰かが正しい方向に私を向けることができます - 私は前にこれをしたことはありません。ここで

+1

'shared_ptr'の通常のポインタ(' * p'と 'p-')は、どちらも正しいことをしています。 – GManNickG

+0

私は間違っているかもしれませんが、未加工のポインタとスマートなポインタの両方を提供することは、問題を求めるように見えます。特に、生ポインタが書き込みを許可する場合。あなたはどんな種類のイテレータを探していますか?もし私があなただったら、私はおそらく、最も単純なもの、例えば、 "ForwardIterator"から始めるでしょう。 – dirkgently

+0

私は 'shared_ptr'が' * p'と 'p->'と同じように動作することを知っています。しばらくの間、私は違いを気にしませんでした。しかし、それはユーザーインターフェイスになると問題です。 APIの他の関数はポインタを引数として取ります。したがって、ユーザがイテレータからオブジェクトを取得した場合、ユーザは未処理のポインタを取得するために 'it-> get()'を使用する必要があります。私は大したことではないと思うが、エンドユーザの観点から見ると、ユーザは基底のオブジェクトが 'shared_ptr'によって保持されていることを知るべきではない。だから、私はそれを図書館全体で一貫させたいと思っています。 –

答えて

5

Boost transform_iteratorを使用してオプションです:

#include <list> 
#include <boost/iterator/transform_iterator.hpp> 
#include <tr1/memory> 
#include <tr1/functional> 

using std::list; 
using std::tr1::shared_ptr; 
using boost::transform_iterator; 
using boost::make_transform_iterator; 
using std::tr1::mem_fn; 
using std::tr1::function; 

struct Foo {}; 

struct Bar 
{ 
    typedef shared_ptr<Foo> Ptr; 
    typedef list<Ptr> List; 
    typedef function< Foo* (Ptr) > Functor; 
    typedef transform_iterator< Functor, List::iterator > Iterator; 

    Iterator begin() 
    { 
    return make_transform_iterator(fooptrs.begin(), mem_fn(&Ptr::get)); 
    } 

    Iterator end() 
    { 
    return make_transform_iterator(fooptrs.end(), mem_fn(&Ptr::get)); 
    } 

    List fooptrs; 
}; 

C++ 11は、それが簡単にfunctionラッパーを排除するためになるだろうが、私はそれをテストするための便利なコンパイラを持っていません。あなたが必要性を見た場合は、(私はAdobeがこの目的のために無料のany_iteratorクラステンプレートを提供していますね。)型の消去を使用してIteratorの具体的な種類をも隠すことができ

+2

+1、そしてポインタの代わりに参照を受け入れることができれば(なぜそうはならないのか分かりません)、Boostには[indirect_iterator <> '](http://www.boost.org/ libs/iterator/doc/indirect_iterator.html)。 – ildjarn

+0

パーフェクト。偉大な例と素晴らしい答え。 –

1

私は時々、人々が実際にboost::shared_ptrときのSTLコンテナの到達を参照しますあまり明白ではなく、比較的少ししか知られていないboost::ptr_containerが良い選択かもしれません。

ptr_containerクラスの素敵なプロパティの1つは、イテレータがan "extra" indirectionであることです。これは、物事をきれいにして安全に保つのに役立ちます。

+0

はい、それは本当です。しかし、この場合、実際には所有権が共有されます。 –

関連する問題