2010-06-22 10 views
5

< Mise à jour > Comme d'habitude pour moi, la question était une mauvaise. La véritable question est la suivante: pourquoi transform_iterator n'utilise-t-il pas la méthode conventionnelle result_of <> metafunction pour déterminer le type de retour, au lieu d'accéder directement à UnaryFunc :: result_type. Posté une réponse avec un travail autour. </Mise à jour >Comment utiliser une expression phoenix avec boost :: transform_iterator?

Plus précisément, est-il un moyen de faire une expression de phénix exposer un type result_type comme prévu pour le concept de std :: unary_function? boost :: transform_iterator semble s'attendre à cela, et en regardant le src de celui-ci, je ne vois pas un simple travail autour.

est ici un code qui reproduit le problème que j'ai eu:

#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 partie relavent du message d'erreur de compilation est ce (gcc 4.3.4, stimuler 1,43):

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

J'ai le même problème avec boost :: lambda (manquant result_type). Je pensais que j'avais vu un usage similaire pour make_transform_iterator et lambda dans le passé, maintenant je me demande si je l'ai simplement imaginé.

Existe-t-il une enveloppe fournie ou un autre mécanisme dans phoenix ou lambda pour exposer result_type?

Répondre

4

Il semble que ceci soit corrigé dans le boost trunk (voir ligne 51, result_of<> au lieu d'un UnaryFunc::result_type indirect). Donc, cela ne devrait pas être un problème dans 1.44 et ci-dessus.

Voici une solution de contournement pour boost < 1.44. L'instanciation transform_iterator accède à UnaryFunc::result_type uniquement si le paramètre de modèle Reference n'est pas fourni. Donc, une astuce consiste à remplacer make_transform_iterator par une version qui appelle la fonction result_of <> meta sur UnaryFunc et utilise le résultat du paramètre Modèle de référence.

#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); 
}; 
Questions connexes