General Iterator std::map Problem

I'm having trouble getting some code to work; I do not know for sure why, but I think it has to do with the way my compiler (TDM-GCC) evaluates a map iterator.

Here is my wrapper code, which I will follow by my test code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
template <typename T, bool IS_CLASS>
class Citerator;

// If we are supplied an int, char,... , we must create an iterator around it.
template <typename TYPE>
class Citerator<TYPE, false> : public std::iterator<std::input_iterator_tag, TYPE>
{
public:

    Citerator(TYPE iterator):m_raw_iterator(iterator){}
    Citerator(const Citerator &iterator):m_raw_iterator(iterator.m_raw_iterator){}
    Citerator &operator=(const Citerator &iterator){m_raw_iterator = iterator.m_raw_iterator; return *this;}

    bool operator==(const Citerator &citerator){return m_raw_iterator == citerator.m_raw_iterator;}
    bool operator!=(const Citerator &citerator){return m_raw_iterator != citerator.m_raw_iterator;}

    TYPE &operator*(){return m_raw_iterator;}
    TYPE &operator->(){return m_raw_iterator;}

    Citerator &operator++(){++m_raw_iterator; return *this;}
    Citerator &operator++(int){m_raw_iterator++; return *this;}

    TYPE &get(){return m_raw_iterator;}

private:

    TYPE m_raw_iterator;

};

// If we are provided an iterator, we inherit from it.
template <typename TYPE>
class Citerator<TYPE, true> : public TYPE
{
public:
    using TYPE::TYPE;
    TYPE &get(){return *this;}
};

// The iterator that wraps around both integers and other iterators.
template <typename TYPE, bool IS_CLASS = std::is_class<TYPE>::value>
class Iterator : public Citerator<TYPE, IS_CLASS>
{
public:
    using Citerator<TYPE, IS_CLASS>::Citerator;
};


And my test code:

1
2
3
4
5
6
7
8
9
10
int main()
{
    Iterator<int> a(0), b(22);

    std::vector<int> ax;
    Iterator<std::vector<int>::iterator> c(ax.begin()), d(ax.end());

    std::map<std::size_t, std::vector<int>> bx;
    Iterator<std::map<std::size_t, std::vector<int>>::iterator> e(bx.begin()), f(bx.end()); // Error occurs here.
}
Last edited on
What is the error message?
@L B

error: no matching function for call to 'Iterator<std::_Rb_tree_iterator<std::pair<const long long unsigned int, std::vector<int> > > >::Iterator(std::map<long long unsigned int, std::vector<int> >::iterator)'|
Clang gives better diagnostics:
http://coliru.stacked-crooked.com/a/025fc7ba1326ca4d

note: candidate constructor (inherited) not viable: no known conversion from 'iterator' (aka '_Rb_tree_iterator<value_type>') to '_Link_type' (aka '_Rb_tree_node<std::pair<const unsigned long, std::vector<int, std::allocator<int> > > > *') for 1st argument

Take a look at a simplified example:

http://coliru.stacked-crooked.com/a/57128b07c505bd43

It appears that when you try to inherit constructors you don't get the special ones (copy ctor, move ctor, etc).
Last edited on
I find that rather odd, considering I have explicitly declared and defined a copy constructor in Citerator, which initializes a member.
I see no such ctor between lines 34 and 38, nor 43 to 46.
Last edited on
You are correct in that; I was thinking of the Citerator when the IS_CLASS is false.

Anyways; I added Citerator(TYPE t){*this = t;} to the Citerator IS_CLASS = true specialization; which does seem to work. I think I understand why this happened.

I'm also thinking about changing std::input_iterator_tag to std::random_access_iterator_tag ?

I read that here (http://en.cppreference.com/w/cpp/iterator/advance) that advance will exploit this for the benefit of the random access iterator's properties.

Thanks for the insight, I'm marking this as solved.
Wow I never knew about inheriting constructors in C++11...I need to read more stuff. (I blame me still using VS2010 which doesn't support it).

Just popping in to say thanks for the new info!
Topic archived. No new replies allowed.