2010-06-22 2 views
5

< Обновление > Как обычно, вопрос был неправильным. Фактический вопрос заключается в следующем: почему transform_iterator не использует обычный result_of <> metafunction, чтобы определить тип возврата, а не напрямую обращаться к UnaryFunc :: result_type. Написал ответ с работой. </Update >Как использовать выражение phoenix с boost :: transform_iterator?

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

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

#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; 
} 

relavent часть сообщения об ошибке при компиляции этого является (GCC 4.3.4, форсирует 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 и лямбда в прошлом, теперь мне интересно, просто ли я это себе представлял.

Есть ли предусмотренная обертка или какой-либо другой механизм в фениксе или лямбда, чтобы выставить result_type?

ответ

4

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

Вот обходной путь для повышения < 1.44. Контекст transform_iterator обращается к UnaryFunc::result_type, только если параметр шаблона Reference не указан. Таким образом, один трюк заключается в замене make_transform_iterator на версию, которая вызывает функцию result_of <> meta на 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); 
}; 
Смежные вопросы