2015-02-04 2 views
1

Примера:
Как объединить несколько диапазонов подталкивания и вернуться в результате из функции без использования подталкивания :: any_range

SomeType bar::foo() const { 
    SomeType retVal; 
    for (auto i = 0u; i < 10; ++i) { 
    retVal = boost::range::join(retVal, m_someDataContainer.equal_range(i)); 
    } 
    return retVal; 
} 


позволяет сказать, для простоты, m_someDataContainer и класс бара определены следующим образом:

typedef boost::multi_index_container< 
    int, bmi::indexed_by<bmi::hashed_unique<bmi::tag<struct someTag>, 
              bmi::identity<int>>>> Data; 
class bar { 
public: 
    SomeType foo() const; 

private: 
    Data m_someDataContainer; 
}; 

вопросов: Как определить тип возвращаемого Foo() и как соединить эти диапазоны без наддува :: any_range

EDIT1: Похоже, что это совершенно невозможно, вызов цикла join в предыдущем объединенном значении делает тип результата вложенным типом join_range of join_range of join_range ... и так далее, что, я думаю, не может быть легко выведено, если на все

+0

Можете ли вы использовать C++ 11? – jrok

+0

в некоторой степени - VS2012 – kreuzerkrieg

+0

Я не знаю, сколько C++ 11 поддерживает VS2012, но если у него есть возвращаемый тип возврата и 'auto', вы в значительной степени настроены. – jrok

ответ

1

Поскольку вы имеете (или можете генерировать) диапазон диапазонов одного типа, вам нужен диапазон сглаживания . Использование Джесси Гуд flatten из Iterating over a range of ranges:

return flatten(boost::irange(0, 10) 
    | boost::adaptors::transform(
     [this](int i){ return m_someDataContainer.equal_range(i); })); 

К сожалению, я думаю, что это будет, вероятно, оставит итераторы оборванным, поэтому вы должны адаптировать flatten там, чтобы скопировать диапазон в возвращаемом значение; вы можете сделать это с множественным наследованием:

template<typename Cont> using FlatIteratorRange 
    = boost::iterator_range<flattening_iterator<decltype(std::declval<Cont>().begin())>; 

template<typename Cont> 
struct FlatRange 
    : private Cont 
    , public FlatIteratorRange<Cont> 
{ 
    explicit FlatRange(Cont const& c) 
     : Cont(c) 
     , FlatIteratorRange<Cont>(
      flat_iter(this->Cont::begin(), this->Cont::end()), 
      flat_iter(this->Cont::end())); 
    {} 
} 

template<typename Cont> 
auto flatten(Cont const& c) -> FlatRange<Cont> 
{ 
    return FlatRange<Cont>(c); 
} 
+0

звучит интересно, завтра это проверит. Я прыгал, я пропускаю что-то фундаментальное в использовании join_range, и есть простое решение. Похоже, я был неправ. – kreuzerkrieg