Как использовать выражение феникса с boost :: transform_iterator? - PullRequest
5 голосов
/ 22 июня 2010

Как обычно для меня, вопрос был неправильным.На самом деле вопрос заключается в следующем: почему transform_iterator не использует обычную метафункцию result_of <> для определения типа возвращаемого значения вместо прямого доступа к UnaryFunc :: result_type.Выложил ответ с обходом.

В частности, есть ли способ заставить выражение феникса отображать тип result_type, как ожидается для концепции std :: unary_function?boost :: transform_iterator, кажется, ожидает этого, и, глядя на исходный код, я не вижу простой обходной путь.

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

#include <boost/iterator/transform_iterator.hpp>
#include <boost/spirit/home/phoenix.hpp>
#include <numeric>
#include <iostream>

using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;

int main(void){
   int i[] = {4,2,5,3};

   std::cout <<
      std::accumulate(
         boost::make_transform_iterator(i,   _1*_1),
         boost::make_transform_iterator(i+4, _1*_1),
         0
      ) << std::endl;

   return 0;
}

Соответствующая часть сообщения об ошибке при компиляции - это (gcc 4.3.4, boost 1.43):

/usr/include/boost/iterator/transform_iterator.hpp:43: error: no type named ‘result_type’ in ‘struct boost::phoenix::actor<...

У меня такая же проблема с boost :: lambda (отсутствует result_type).Я думал, что я видел подобное использование для make_transform_iterator и lambda в прошлом, теперь я задаюсь вопросом, только ли я себе это представил.*?

1 Ответ

4 голосов
/ 22 июня 2010

Похоже, что это исправлено в магистральной линии (см. Строку 51, result_of<> вместо косвенного UnaryFunc::result_type). Так что это не должно быть проблемой в 1.44 и выше.

Вот обходной путь для повышения <1,44. Инстанциация transform_iterator обращается к <code>UnaryFunc::result_type, только если не указан параметр шаблона Reference. Итак, одна хитрость заключается в замене make_transform_iterator версией, которая вызывает мета-функцию result_of <> в UnaryFunc, и использует результат для параметра шаблона Reference.

#include <boost/iterator/transform_iterator.hpp>
#include <boost/utility.hpp>
#include <iterator>

template <class UnaryFunc, class Iterator>
boost::transform_iterator<
   UnaryFunc,
   Iterator,
   typename boost::result_of<
      UnaryFunc(typename std::iterator_traits<Iterator>::value_type)
   >::type
>
make_trans_it(Iterator it, UnaryFunc fun){
   return
      boost::transform_iterator<
         UnaryFunc,
         Iterator,
         typename boost::result_of<
            UnaryFunc(typename std::iterator_traits<Iterator>::value_type)
         >::type
      >(it, fun);
};
...