Home > Net >  In template<class It> function where It is an iterator, can I make It::value_type work for bot
In template<class It> function where It is an iterator, can I make It::value_type work for bot

Time:10-31

I have been writing some functions that take a template called It, which should be an iterator. Then I use the It::value_type for some functionality. This has been working for most containers I have tried but fails for std::array. If I do use an std::array I get the error

error: ‘long unsigned int*’ is not a class, struct, or union type

So I see the problem, the iterator for the std::array is just a pointer, which makes sense to me. Therefore it has no ::value_type defined. But how can I make my templated code so that this works for std::array and std::vector, std::list etc?

I made a MWE, the function in it just a silly pathological example that shows my problem

#include <vector>
#include <iostream>
#include <array>

template <class It>
void print_accumulate(It first, It last) {
    typename It::value_type result{};    // What do I write here??
    while (first != last) {
        result  = *first;
          first;
    }
    std::cout << result << "\n";
}

int main() {
    std::vector<size_t> v = {1, 2, 3, 4, 5}; /* Replacing with std::array<size_t, 5> gives error */
    print_accumulate(v.begin(), v.end());
}

The above works just fine for just about every container I've tried, vector, list, set etc. However, when I try to run the code by replacing the std::vector<size_t> with std::array<size_t, 5>, i get the error message I gave.

Thanks in advance!

CodePudding user response:

Use iterator_traits

template <class It>
void print_accumulate(It first, It last) {
    typename std::iterator_traits<It>::value_type result{};    // use iterator_traits
    while (first != last) {
        result  = *first;
          first;
    }
    std::cout << result << "\n";
}


  • Related