Обертка на итератор
От: Tuo_Bellas Россия  
Дата: 01.12.05 17:33
Оценка:
Всем привет!

class ElementWrapper;

typedef /*???*/ SomeIteratorType;

class BaseStorage
{
public:
  virtual SomeIteratorType GetGoodElements() = 0;
  virtual ~BaseStorage() { };
};

template <class Element>
class Storage
  : public BaseStorage
{
public:
  virtual SomeIteratorType GetGoodElements()
  {
    return boost::make_transform_iterator(
        boost::make_filter_iterator(
            IsElementGood,
            m_Elements.begin(),
            m_Elements.end()
          ),
        boost::bind(
            MakeElementWrapper,
            this
          )
      );
  }

  size_t GetNumElements() const { return m_Elements.size(); }

private:
  typedef boost::shared_ptr<Element> ElementPtr;
  typedef std::vector<ElementPtr> Elements;
  Elements m_Elements;

  static bool IsElementGood(const ElementPtr & pElement);
  ElementWrapper MakeElementWapper(const Elements::iterator & theElement);
};

/* ... */

typedef boost::shared_ptr<StorageBase> StorageBasePtr;
std::vector<StorageBasePtr> allStorages;

typedef std::vector<ElementWrapper> GoodElements;
GoodElements allGoodElements;

//  Copy all good elements from all storages to allGoodElements.
allGoodElements.reserve(GetNumOfAllElements(allStorages));
std::for_each(
    allStorages.begin(),
    allStorages.end(),
    boost::bind(
        GoodElements::insert,
        boost::ref(allGoodElements),
        boost::bind(GoodElements::end, boost::ref(allGoodElements)),
        boost::bind(StorageBase::GetGoodElements, boost::bind(StorageBasePtr::get, _1)),
        SomeIteratorType()
      )
  );


(Код из головы.)

Вычислить и записать тип SomeIteratorType, конечно, можно (если я нигде не ошибся в этом примере). Только он будет длинный, да и, на самом деле, на уровне интерфейса StorageBase это деталь реализации — ведь GetGoodElements() — чисто виртуальная функция.

Можно ли здесь что-либо сделать? (Кроме передачи allGoodElements в GetGoodElements() для заполнения.)

Спасибо,
Tuo_Bellas.

P.S. Или я опять перемудрил?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.