диапазон усиления

У меня есть карта, где значение является слабым указателем. Это работает:
Пока я могу написать это:

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();
}

однако я не смог понять, как должно выглядеть это преобразование; или если это даже должно быть преобразование.

У кого-нибудь есть идея? Я убежден, что эта модель может быть довольно распространенной.

3

Решение

Вот пример, который я буквально просто бросил вместе:

#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;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]