Search code examples
c++templatesdictionaryiteratorpartial-specialization

Partial class template specialization with maps


I'm a new C++ programmer, I learned Java and ANSI C a time ago and decided to give it a shot.

Well, I love C++, but I didn't like how the iterators work:

In java, you could make a whole container private and implement a getter function to it's iterator, and the iterator has a method hasNext() that returns a boolean depending on if it has reached the end of the container.

The only way I found to do something similar on C++ is writing 2 getters, iteratorBegin() and iteratorEnd(), that returned an interator corresponding to the first and last positions, incrementing the iterator returned by iteratorBegin() and comparing it with iteratorEnd(), allowed me to iterate over the container until the final position had been reached

But, I want to use only ONE getter method, and I thought: "Let's make my own iterator class"

So far so good, I've done it successfully with sets and lists, but I can't seem to make it with maps, here's the code that's troubling me: (the class is defined in a separate .h, this is called customIterator.cpp)

template<typename T, typename D>
const D& custIterator<T,D>::next()
{
    const D& obj = (*it);
    if(hasNext())
    {
        it++;
    }
    return obj;
}

//the above works fine

template<typename T, typename D>
const D& custIterator<map<T,D>,D>::next() //error in this line
{
    D& obj = (*it).second; 
    if(hasNext())
    {
        it++;
    }
    return obj;
}

when compiling the specialized method, it says: error: ‘map’ was not declared in this scope even though I added #include <map> on top of the file

I'm using gcc version 4.4.5 (Debian 4.4.5-8) with codeblocks

Please, I need some assistance.

Thanks for your attention!


Solution

  • All the standard containers are inside the namespace std, you should qualify it thus

    std::map<T,D>
    

    In general I would recommend not trying to carry over Java idioms to C++ since each language has its own idioms and mixing them will confuse other programmers (just as I think that #define BEGIN { isn't the best idea ever).

    What you're trying to do is known as ranges and is considered by some to be a better solution than C++ iterators but until it makes its way into the language I think it's harmful for each developer to invent their own ranges.

    Further reading or tl;dr slides (there's a video to go with this which I can't find at the moment).