Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Must a template friend operator overload precede a member function overload of the same operator?

Does anybody know why this compiles:

template<typename T>
class Foo;

template<typename T>
bool operator==(const T& l, const Foo<T>& r); 

template<typename T>
class Foo 
{
public:
    Foo();
    ~Foo();

    friend bool operator== <> (const T& l, const Foo<T>& r); 

    bool operator==(const Foo<T>& r);
};

But this does not (only difference is order of member vs friend operator==):

template<typename T>
class Foo;

template<typename T>
bool operator==(const T& l, const Foo<T>& r); 

template<typename T>
class Foo 
{
public:
    Foo();
    ~Foo();

    bool operator==(const Foo<T>& r);

    friend bool operator== <> (const T& l, const Foo<T>& r); 
};

I was banging my head against the second case, with an "error: declaration of ‘operator==’ as non-function" at the friend line. I finally decided there must be something wrong before the friend declaration, so I tried moving it up in the code to see if I could get a different error. Lo and behold, when I moved it above the member declaration, everything worked!

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It’s because after declaring a member operator== in the scope of the class, the name operator== will refer to that instead of the global template.

I’m not sure that’s the correct behaviour (might be a compiler bug, may also fall foul of https://stackoverflow.com/a/15538759/5754656), but what’s happening is that operator== is parsed as a non-template, so the next < is a less than sign rather than part of a template-id.

Qualifying it so that the non-member operator== is found instead fixes this:

template<typename T>
class Foo 
{
public:
    Foo();
    ~Foo();

    bool operator==(const Foo<T>& r);

    //friend bool operator== <> (const T& l, const Foo<T>& r);
    friend bool ::operator== <> (const T& l, const Foo<T>& r);
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading