2010-09-09 14 views
0

Normalement, quelqu'un allait simplement prendre le Function Output Iterator de Boost, mais je ne suis pas autorisé à utiliser Boost au travail. Cela dit, je veux juste utiliser la fonction copy pour parcourir une collection, appeler une fonction sur chaque élément, prendre la sortie de cette fonction, et enfin push_back sur une autre collection. J'ai écrit du code:Boost: Fonction Iterator de sortie, réinventer la roue

#include <iterator> 
using std::iterator; 
using std::output_iterator_tag; 

template<typename Container, typename Function> 
struct Back_Transform_Iterator : public iterator<output_iterator_tag,void,void,void,void>{ 
    explicit Back_Transform_Iterator(Container &_container, const Function &_function) 
     : m_Container(_container), 
     m_Function(_function){} 

    Back_Transform_Iterator<Container,Function>& operator= (const typename Function::argument_type &value){ 
     m_Container.push_back(m_Function(value)); 

     return *this; 
    } 

    Back_Transform_Iterator<Container,Function>& operator*(){ return *this; } 
    Back_Transform_Iterator<Container,Function>& operator++(){ return *this; } 
    Back_Transform_Iterator<Container,Function> operator++ (int){ return *this; } 

    typedef Container container_type; 

private: 
    Container &m_Container; 
    Function m_Function; 
}; 

template<typename C, typename F> 
Back_Transform_Iterator<C,F> back_transform_inserter(C &_container, F &_unary_function){ 
    return Back_Transform_Iterator<C,F>(_container, _unary_function); 
} 

mais ... Je rencontre des problèmes de compilation. Assez sûr que c'est à voir avec l'appel operator*(). Je n'ai aucune idée de la façon de déréférencer efficacement les objets du conteneur afin qu'ils puissent objecter les effets de la fonction. Erreur:

error C2582: 'operator =' function is unavailable in 'Back_Transform_Iterator<Container,Function>' 

Les éléments dont je suis en train d'itérer ne sont pas modifiables. Quelqu'un sait comment s'attaquer à ce problème?

+2

une raison quelconque vous ne l'utilisez pas 'std :: transform' et 'back_inserter'? –

+0

Gah! Mettez-le comme une réponse et laissez-moi vous donner le crédit pour cela. – wheaties

Répondre

5

Vous pouvez utiliser transform à la place:

transform(src.begin(), src.end(), back_inserter(container), func); 

Notez que const appliqué sur un type de référence est un no-op. Donc, si argument_type est T&, alors dire const argument_type ne donne pas de retour const T& mais T& nouveau. Donc, si vos éléments source sont constants que vous essayez de les lier au paramètre de référence non-const de operator= dans le cas où argument_type est une référence:

typedef int &intr; 
const intr& a = 0; // fails - "const" is ignored! 
+0

Atteint ma limite quotidienne de upvotes, devra revenir plus tard pour vous donner un +1. – wheaties