Question

I implemented a Simple STL map in C++. Factored out the comparison as a type as I was instructed to, then implemented the comparison as shown below:

template <typename T> int KeyCompare<T>::operator () (T tKey1, T tKey2)
{

        if(tKey1 < tKey2)
        return -1;
    else if(tKey1 > tKey2)
        return 1;
    else 
        return 0;
} 

here, tKey1 and tKet2 are the two keys I'm comparing. This worked well for all the basic data types and string. I added a template specialization to compare keys of a user defined type named Test and added a specialization as follows:

int KeyCompare<Test>::operator () (Test tKey1, Test tKey2)
{

        if(tKey1.a < tKey2.a)
        return -1;
    else if(tKey1.a > tKey2.a)
        return 1;
    else 
        return 0;
}

when I run this, I get a linking error saying

SimpleMap.obj : error LNK2005: "public: int __thiscall KeyCompare::operator()(class Test,class Test)" (??R?$KeyCompare@VTest@@@@QAEHVTest@@0@Z) already defined in MapTest.obj

SimpleMap.obj : error LNK2005: "public: __thiscall KeyCompare::~KeyCompare(void)" (??1?$KeyCompare@VTest@@@@QAE@XZ) already defined in MapTest.obj

SimpleMap.obj : error LNK2005: "public: __thiscall KeyCompare::KeyCompare(void)" (??0?$KeyCompare@VTester@@@@QAE@XZ) already defined in MapTest.obj

MapTest.cpp is the test harness class in which I wrote the test case. I have used include guards as well, to stop multiple inclusions.

Any idea what the matter is??

Thank you very much!!

Was it helpful?

Solution

That’s not a specialization.

Also, please show the whole code. You seem to have templatized the operator () method. This is rather unorthodox. Instead, templatize the whole class and specialize it properly.

So instead of your code, write something like this:

template <typename T>
struct KeyCompare {
    int operator ()(T const& key1, T const& key2) const {
        // Comparison logic here …
    }
};

And then specialize the class:

template <>
struct KeyCompare<Test> {
    int operator()(Test const& key1, Test const& key2) const { … }
};

This is slightly more code but makes it truly extensible (since anyone can add their own specialization implementation without having to modify existing code). This is also the way that other C++ libraries (in particular the STL) work.

OTHER TIPS

You don't need a specialisation - simply overload it:

int KeyCompare::operator () (Test tKey1, Test tKey2)
{

        if(tKey1.a < tKey2.a)
        return -1;
    else if(tKey1.a > tKey2.a)
        return 1;
    else 
        return 0;
}

And you should be passing the parameters t all these compare functions as const references.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top