Настройка
Если вы хотите иметь итераторы, которые вертятся с тем, что они повторяют, прежде чем возвращать его, boost::transform_iterator
довольно хороши. Вы передаете им унарную функцию, которая преобразует результат базового итератора operator*()
, а затем преобразующий итератор возвращает это:
template<typename Map>
struct iterator_transform_traits_map_second {
typedef typename Map::value_type value_type;
typedef typename Map::mapped_type result_type;
result_type& operator()( value_type& v) const {return v.second;}
const result_type& operator()(const value_type& v) const {return v.second;}
};
typedef
boost::transform_iterator<iterator_transform_traits_map_second>
transformed_iterator;
До сих пор так хорошо. Но.
Какой беспорядок это приводит к
Ваши сотрудники как этот блестящий новый инструмент, а также начинают использовать его, и довольно скоро кто-то собирает в заголовке то, что вы все придумали до сих пор. Здесь наш:
-
iterator_transform_traits_map_first
-
iterator_transform_traits_map_second
-
iterator_transform_traits_map_deref
(разыгрывает любую запись контейнера) -
iterator_transform_traits_map_deref_second
(разыгрывает запись картыsecond
) -
iterator_transform_traits_map_dynamic_cast
(выполняетdynamic_cast<>()
любую запись контейнера) -
iterator_transform_traits_map_any_second
(выполняет записьany_cast<>()
на картеsecond
)
Конечно, это оставляет много полезных (потому что их еще никто не нужен), а не масштабируется вообще. Мне просто было поручено написать итератор, который разделяет запись карты second
и делает dynamic_cast<>()
, и я являюсь тем, кому я отказываюсь просто добавлять iterator_transform_traits_map_dynamic_cast_deref_second
и двигаться дальше.
Что я хочу
Вместо этого я пытаюсь написать несколько базовых признаков и составляющих времени компиляции, которые позволяют назвать пару из них в качестве параметров шаблона и просто конвейерные вызовы. В идеале я хочу что-то вроде этого:
typedef
boost::transform_iterator<
iterator_transform_traits< iter_transf_tr_second
, iter_transf_tr_deref
, iter_transf_tr_dynamic_cast<derived>
>
>
transformed_iterator;
Моя текущая идея состоит в том, чтобы рекурсивно получить шаблон-оболочку и иметь, что рекурсивно вызывает все черты, передавая результат от одного к другому. Я сделал что-то подобное десять лет назад и имею базовое представление о том, как это сделать. Тем не менее, в последний раз, когда я это делал, я шел пешком. То есть, я сам реализовал все шаблоны метамагии.
Это глупо, конечно, учитывая, что у нас теперь есть boost.mpl, boost.fusion и т.д., поэтому я бы скорее использовал то, что уже было. Тем не менее, после того, как он во второй половине дня возился с этим, я понял, что у меня будет много уроков, прежде чем я это сделаю. И хотя я не против узнать все это, у меня есть кто-то, дышащий мне на шею, которому нравится то, что я делаю, но говорит, что ему все равно нужно вытащить штепсель, потому что есть этот крайний срок... У меня теперь есть выбор, чтобы просто напишите проклятый iterator_transform_traits_map_dynamic_cast_deref_second
, скопируйте много кода, который гниет в течение десятилетия и строится на нем, или придумайте чистое решение.
То, куда вы вошли.
Вопрос
Как вы могли бы реализовать эти сложные черты, используя то, что уже есть?
Платформа
Однако существует одна проблема . Мы находимся на встроенной платформе и застреваем с GCC 4.1.2, что означает С++ 03, TR1 и увеличить 1,52. Нет аргументов шаблона переменной, нет decltype
и всего, что причудливо.