2013-04-01 40 views
3

我有一個地圖,其中的值是一個弱指針。這工作: 雖然我可以這樣寫:升壓範圍weak_ptr

for_each(IFoo::foo_wptr obj, objects | range::map_values) { 
    IFoo::foo_ptr myObj = obj.lock(); 
    if(myObj) myObj->notify(); 
} 

我寧願有轉變爲鎖定共享指針新的範圍。類似這樣的:

for_each(IFoo::foo_ptr obj, objects | range::map_values | range::locked) { 
    if(obj) obj->notify(); 
} 

但是,我一直無法弄清楚那個轉換應該是什麼樣的;或者如果它甚至應該是一個轉換。

有沒有人有想法?我相信這種模式可能相當普遍。

+1

你嘗試按照手冊:http://www.boost.org/doc/libs/1_53_0/libs/range/doc/ html/range/reference/extends/method_3.html?那裏描述的方法沒有工作嗎? –

回答

0

下面是我從字面上只是把在一起的例子:

#include <boost/iterator/transform_iterator.hpp> 
#include <boost/range/iterator_range.hpp> 
#include <boost/range/adaptor/map.hpp> 
#include <boost/iterator/transform_iterator.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 
#include <boost/weak_ptr.hpp> 
#include <boost/foreach.hpp> 
#include <map> 
#include <vector> 

struct weak_ptr_locker 
{ 
    template <typename Sig> 
    struct result; 

    template <typename F, typename T> 
    struct result<F(boost::weak_ptr<T>&)> 
    { 
     typedef boost::shared_ptr<T> type; 
    }; 

    template <typename T> 
    boost::shared_ptr<T> operator()(const boost::weak_ptr<T>& pWeak) const 
    { 
     return pWeak.lock(); 
    } 
}; 

template<typename R> 
struct lock_transform_range : 
    boost::iterator_range< boost::transform_iterator< weak_ptr_locker, typename   boost::range_iterator<R>::type> > 
{ 
private: 
    typedef boost::iterator_range< boost::transform_iterator< weak_ptr_locker, typename  boost::range_iterator<R>::type> > base; 

public: 
    typedef boost::transform_iterator< weak_ptr_locker, typename  boost::range_iterator<R>::type > iterator; 

    lock_transform_range(R& r) 
     : base(iterator(boost::begin(r)), iterator(boost::end(r))) 
    {} 
}; 

namespace detail 
{ 
    struct lock_transform_forwarder {}; 
} 

template< class BidirectionalRng > 
inline lock_transform_range<BidirectionalRng> operator | (BidirectionalRng& r,  detail::lock_transform_forwarder) 
{ 
    return lock_transform_range<BidirectionalRng>(r); 
} 

template< class BidirectionalRng > 
inline lock_transform_range<const BidirectionalRng> operator | (const BidirectionalRng&  r, detail::lock_transform_forwarder) 
{ 
    return lock_transform_range<const BidirectionalRng>(r); 
} 

namespace 
{ 
    const detail::lock_transform_forwarder locked = detail::lock_transform_forwarder(); 
} 

struct Foo 
{ 
    Foo(int i) 
     : i(i) 
    {} 

    int i; 
    void notify() 
    { 
     std::cout << i << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    typedef std::map<int, boost::weak_ptr<Foo> > Map; 
    typedef boost::shared_ptr<Foo> FooPtr; 
    Map objects; 

    std::vector<FooPtr> storage; 
    for (int i = 0; i < 10; ++i) 
    { 
     storage.push_back(boost::make_shared<Foo>(i)); 
     objects[i] = storage.back(); 
    } 

    using namespace boost::adaptors; 
    for_each(FooPtr obj, objects | map_values | locked) 
    { 
     if (obj) 
      obj->notify(); 
    } 
    return 0; 
}