views:

68

answers:

2

Hi,

I' m implementing a custom STL map. I need to make sure that any data type (basic or user defined) key will work with it. I declared the Map class as a template which has two parameters for the key and the value. My question is if I need to use a string as the key type, how can I overload the < and > operators for string type keys only?? In template specialization we have to specialize the whole class with the type we need as I understand it. Is there any way I can do this in a better way?? What if I add a separate Key class and use it as the template type for Key?

Thank You!!

+2  A: 

You should factor out the comparison as a type, like the normal std::map does. That is, have a utility class less_compare:

template <typename T>
struct less_compare
{
    bool operator()(const T& pLhs, const T& pRhs) const
    {
        return pLhs < pRhs;
    }
};

And then:

template <typename Key, typename Value, typename Compare = less_compare<Key> >
class map
{
    // ...

private:
    Compare mCompare;
};

And to compare two values, do: if (mCompare(someThing, someOtherThing)), which will be true with someThing is "less than" someOtherThing. Note this factoring also allows user-defined comparisons (which is why "less than" is quoted). This is known as policy-based design.

And now you can specialize just the less_compare class for C-strings. (And also provide greater_compare and kin.)


Do keep in mind, unless this is for learning, you should not be implementing your own map. Also note that std::string has operator< overloaded already.

GMan
Thanks a lot for the immediate reply, and yes it is for learning purposes. I'm new to templates so I wanted to get my hands a bit dirty :D
Just out of curiosity, but why shouldn't we be implementing our own maps??
@isurulucky: Since you're doing it for practice, it's okay. But in general you shouldn't waste time with something that's already done. (If you need a map include `<map>` and use `std::map`.) Especially since things that are already done have been (and are) heavily optimized and tested.
GMan
Hi I did what you said. It worked well so far. But when I change the code of () overload, to work with a user defined object (say a struct with an integer in it), I get some link errors again, saying operator () is already defined. What is the matter here??PS : I have used include guards as well.
@isurulucky: I'd start a new question with that. Make sure you include all the relevant code.
GMan
@GMan: Ok, did it just now :)
A: 

You could also use type traits. It will give you a framework to solve also the possible future differences between types.

FireAphis