J'essaie d'implémenter un simple ostream_itreator, qui diffuse chaque N-ième élément, mais j'obtiens une erreur de type

error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’
       typedef typename iterator_traits<_OI>::value_type _ValueTypeO;

Code:

#include <iostream>
#include <vector>
#include <iterator>


template<class T>
class outIterator {
    std::ostream *stream;
    size_t N;
    const char* delim;
    size_t counter = 0;
public:
    // initialization
    outIterator(std::ostream& out)
    : stream(&out)
    , N(1)
    , delim(" ")
    {}

    outIterator(std::ostream& out, size_t N, const char* delimiter)
    : stream(&out)
    , N(N)
    , delim(delimiter)
    {}

    // =
    outIterator<T>& operator= (const T& value) {
        if (counter % N == 0){
            *stream << value << delim;
        }
        return *this;
    }
};

int main() {
    outIterator<int> out(std::cout, 2, " ");
    std::vector<int> vec {0, 1, 2, 3, 4, 5};
    std::copy(vec.begin(), vec.end(), out);
    return 0;
}

De plus, je n'ai pas inclus les surcharges ++ et ++ (int). Ils incrémentent le compteur et renvoient *this. Et * surcharge qui renvoie *ceci

Erreur de description:

/usr/include/c++/7/bits/stl_algobase.h:378:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’
       typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
                                                         ^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:383:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’
       const bool __simple = (__is_trivial(_ValueTypeI)
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~
                       && __is_pointer<_II>::__value
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       && __is_pointer<_OI>::__value
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         && __are_same<_ValueTypeI, _ValueTypeO>::__value);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
Dmitry Kuznetsov 22 janv. 2020 à 04:44

2 réponses

Meilleure réponse

Les types d'itérateurs personnalisés doivent contenir des définitions de type de membre pour difference_type, value_type, pointer, reference et iterator_category ou se spécialiser std::iterator_traits pour fournir le même .

Dans votre cas particulier, vous devez modifier votre modèle outIterator comme ceci :

template <typename T>
class outIterator {
//...
public:
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::output_iterator_tag;
//...
};
5
Miles Budnek 22 janv. 2020 à 02:39

Lorsque vous écrivez votre itérateur, vous devez inclure une variable. Il vous suffit d'inclure ceux-ci :

template <class T>
class iterator {
    public:
        // code ...   
        using iterator_category = std::forward_iterator_tag;
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = value_type*;
        using reference = value_type&;
        // code ...
 }
0
Nicholas Pilotto 1 avril 2021 à 08:38