Home > OS >  Encountring error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<std::vector&
Encountring error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<std::vector&

Time:06-10

I am trying to create a program which will sort the sequence on integers based on iterators (whether forward iterator or random access iterator). But I am encountering this error when I am trying to pass vector:

error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<std::vector<int> >

Same issue I am encountering while passing forward_list also:

error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<std::forward_list<int> >’

Here is my code:

#include<iostream>
#include<vector>
#include<forward_list>
#include<iterator>
#include<algorithm>
#include<typeinfo>
using namespace std;

template<typename Ran>
void sort_helper(Ran beg, Ran end, random_access_iterator_tag){
    /*
    Random access iterator version of sort
    */
    sort(beg, end);
}

template<typename For>
void sort_helper(For beg, For end, forward_iterator_tag){
    /*
    The version for forward iterators is almost as simple; just copy the list into a vector, sort, and copy
    back again:
    */
    vector<decltype(*beg)> vec{beg, end};
    sort(vec.begin(), vec.end());
    copy(vec.begin(), vec.end(), beg);

}

template<class Iter>
void testSort(Iter& c){
    sort_helper(c.begin(), c.end(), typename std::iterator_traits<Iter>::iterator_category{});
}

int main(int argc, char** argv){
    vector<int> vec = {3, 5, 1, 2, 3, 1, 5, 88};
    forward_list<int> flst = {6, 4, 6, 1, 4, 77, 1, 23, 2, 4};

    testSort(vec);
    testSort(flst);

    for(auto& x:vec){
        cout<<x<<" ";
    }cout<<"\n";

    for(auto& x:flst){
        cout<<x<<" ";
    }cout<<"\n";
}

CodePudding user response:

In your testSort() function, the Iter template argument (whose name is misleading, BTW) is receiving the container type, but iterator_traits wants an iterator type instead.

This will work in your example:

template<class Container>
void testSort(Container& c){
    sort_helper(c.begin(), c.end(),
        typename std::iterator_traits<typename Container::iterator>::iterator_category{}
    );
}

However, that will not work for raw C-style arrays, which don't have begin(), end(), or iterator members. But this will work for them:

template<class Container>
void testSort(Container& c){
    sort_helper(std::begin(c), std::end(c),
        typename std::iterator_traits<decltype(std::begin(c))>::iterator_category{}
    );
}

Another problem is, this line also fails to compile:

std::vector<decltype(*beg)> vec{beg, end};

This is because dereferencing an iterator returns a reference to the element being referred to, so decltype(*beg) returns a reference type, which prevents the vector::pointer and vector::const_pointer members from being declarable:

error: forming pointer to reference type ‘int&’

This will work:

std::vector<typename std::remove_reference<decltype(*beg)>::type> vec{beg, end};

However, you can use iterator_traits here instead, which has a value_type member:

std::vector<typename std::iterator_traits<For>::value_type> vec{beg, end};
  • Related