Domanda

Come al solito per me, la domanda era una sbagliata. La domanda reale è: perché non utilizzare il transform_iterator result_of convenzionale <> metafunction per determinare il tipo di ritorno, invece di accedere direttamente UnaryFunc :: result_type. Pubblicato una risposta con un giro di lavoro.

In particolare, c'è un modo per fare un espressione fenice esporre un tipo di result_type come previsto per lo std :: concetto di unary_function? boost :: transform_iterator sembra aspettarsi questo, e guardando lo src di esso, non vedo un semplice giro di lavoro.

Ecco un po 'di codice che riproduce il problema ho avuto:

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

La parte relavent del messaggio di errore da compilare questo è (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<...

Ho lo stesso problema con boost :: lambda (manca result_type). Ho pensato che avevo visto l'utilizzo simile per make_transform_iterator e lambda, in passato, ora mi chiedo se ho solo immaginato.

C'è un wrapper fornito o qualche altro meccanismo a Phoenix o lambda per esporre result_type?

È stato utile?

Soluzione

Sembra che questo è stato risolto di spinta tronco (vedi linea 51, result_of<> invece di un UnaryFunc::result_type indiretta). Quindi questo non dovrebbe essere un problema in 1,44 e al di sopra.

Ecco una soluzione per spinta <1.44. Gli accessi transform_iterator di istanza UnaryFunc::result_type solo se il parametro modello Reference non è previsto. Quindi, un trucco è quello di sostituire make_transform_iterator con una versione che chiama il result_of <> meta funzione sul UnaryFunc e usare il risultato per il parametro del modello di riferimento.

#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);
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top