0

i'm stuck with a little problem: i have a unordered_set which contain a struct. I have already implemented the hash function. But when i have first compiled my program, i 'v got some compiler error saying that i haven't implemented a overloaded "operator==".

The problem is that when i declare my overloaded:

bool operator==(mapPoint const& p1, mapPoint const& p2){
    return p1.x == p2.x && p1.y == p2.y;
}

I've got some linker error. In every file where the header is included, i've got the error message (uplicate symbol __XXXX_mapPointS1_).

The fact is it works fine when it's put into the implementation file, where i use it with the unordered_set.

My question is, how can i resolve this problem? There are so much magic beyond the compiler than i can't understand it. hanks

Mr Bonjour
  • 3,330
  • 2
  • 23
  • 46
  • 1
    Looks like your `operator==` has external linkage. Either make it `inline` or put the implementation (= function definition / body) in a source file rather than the header. – dyp Jun 06 '13 at 15:52
  • possible duplicate of [Duplicate symbols with header only implementation](http://stackoverflow.com/questions/13447471/duplicate-symbols-with-header-only-implementation) – n. m. could be an AI Jun 06 '13 at 16:10

1 Answers1

1

You understand that it don't have that problem when you put it in an implementation file.

The C++ compiler does not have any notion of headers and implementation files. It merely knows of "translation units", the cpp files. The header files are included by the C preprocessor. The compiler only sees a single file. If you define a function in a header which is included by several cpp files, and that function has external linkage, then the linker will complain about duplicate definitions.

Generally, you should only keep in headers definitions for inline functions.

If you still want to do it you have to avoid external linkage, either by declaring the function inline, or by declaring it static, or by declaring it inside a namespace without a name (which is the C++ way of defining stuff internally to a translation unit).

namespace // local
{
    bool operator==(mapPoint const& p1, mapPoint const& p2)
        { return p1.x == p2.x && p1.y == p2.y; }
}

or, a bit ugly and C-ish:

static bool operator==(mapPoint const& p1, mapPoint const& p2)
    { return p1.x == p2.x && p1.y == p2.y; }

or, because this function looks like a good candidate for inlining:

inline bool operator==(mapPoint const& p1, mapPoint const& p2)
    { return p1.x == p2.x && p1.y == p2.y; }
migle
  • 881
  • 8
  • 11
  • Thank you migle for your help. Making it inline work like a charm. The fact that i had to give one implementation of (==) without using it (because of unordered_set) make me big in trouble. I have tried the namespace trick in a header, but the compiler was complaining about not finding it. So i was kind of confused because in c++ books they put the (==) stuff bare in the implementation file, witch was kind of a problem to me. I really appreciate your help. Thank you! – Mr Bonjour Jun 07 '13 at 06:56
  • You can put it in the implementation file, as long as the other translation units see a declaration of the function. That is to say, `extern bool operator ==(mapPoint const&, mapPoint const&);` with nothing more (the function is declared but not defined). – migle Jun 07 '13 at 17:57