Гибкая мутация контейнеров последовательностей в C ++ - PullRequest
0 голосов
/ 21 июня 2010

Я обдумываю текущее ограничение итераторов STL и задаюсь вопросом, есть ли изящный способ обойти это.Вот моя ситуация: у меня есть класс, который инкапсулирует контейнер последовательности и универсальный метод для изменения содержимого контейнера, например:

class Container {
  typedef std::vector<int> Data;
  Data data_;
 public:
  template <class Mutator>
  ?? mutate() {
    Mutator m;
    return m(??);
  }
};

Некоторые детали были опущены для краткости, но главная проблема, которую яЯ рассматриваю, что передать мутатору (вызов функции m ()).Вторичный вопрос заключается в том, что нужно вернуть из мутата, чтобы разрешить простой состав мутаторов.Одна из возможностей - передать (и вернуть) пару итераторов начала / конца в data_ или даже boost :: sub_range, например:

template <class Mutator>
boost::sub_range<Data> mutate() {
  Mutator m;
  return m(boost::sub_range<Data>(data_);
}

Это позволит мне делать большую часть того, что я хочуна данных, таких как отрицание всех значений в диапазоне, умножение на коэффициент и т. д. Это также позволяет мне связывать или составлять различные мутаторы, как в этой (сокращенной) версии:

return m1(m2(m3(data_)));

Таким образом,любой мутатор может, например, выбрать поддиапазон своего входа, чтобы ограничить диапазон, на котором работают внешние мутаторы, - желательная особенность.И все эти мутаторы могут изменять данные на месте, что очень эффективно.

Однако этот синтаксис не может изменить размер контейнера (по крайней мере, с вектором), поэтому мутаторы, которые вставляютили удалить элементы не может работать с интерфейсом на основе итератора.Альтернативный интерфейс передает весь контейнер мутатору.Я не уверен, как справиться с поддиапазоном в этом случае, и это также выглядит как менее элегантное решение, чем общее решение с минимальными требованиями, основанное на итераторах.

Буду признателен за любые идеи о том, как действоватьс этим ограничением.

1 Ответ

0 голосов
/ 21 июня 2010

Вы можете комбинировать функторы (Think: Function Composition) с boost :: bind .

С другой стороны, я чувствую, что не до конца понимаю: должен ли второй функтор работать в другом диапазоне, чем первый функтор? Будут ли данные удалены из контейнера?

Имейте в виду: текущее решение имеет неочевидные затраты: каждая композиция «мутаторов» потребует новой итерации вместо того, чтобы быть «реальной композицией мутаторов».

...