2

I am learning C++ using the books listed here. Now, to further check that I've understood the concepts I'm also writing simple sample programs. One such program that compiles with msvc but does not compile with clang and gcc is given below. Demo.

template<typename P> struct C{
template<typename T>
    struct E
    {
        template<typename U = P, typename V = T>
        friend bool operator==(const typename C<U>::template E<V>&, 
                               const typename C<U>::template E<V>&);
    };
};

int main()
{
    C<int>::E<double> d1, d2;
    
    std::cout<<(d1==d2);      //compiles with msvc but rejected in gcc and clang
}

So, my question is which compiler is right here(if any) according to the standard.

Jason
  • 36,170
  • 5
  • 26
  • 60
Kal
  • 475
  • 1
  • 16
  • @BernieD Different compilers are giving different error messages.And the error messages are also too long/complicated/unreadable. It compiles without any error with msvc. – Kal Sep 24 '22 at 09:54
  • Please write complete and precise examples when asking a language-lawyer question. Your program is obviously not well-formed (even if I add the missing `#include`s), because even if declarations and overload resolution are fine, then there is still a missing definition of `operator==` violating the ODR rule. You would see that in practice only at the linker stage though. So I expect that you really intent to have a definition for the function template somewhere as well and the question then is where and how you place this definition. – user17732522 Sep 24 '22 at 10:10

1 Answers1

4

MSVC is wrong in accepting the code as it is ill-formed. This can be seen from temp.param#12 which states:

If a friend function template declaration specifies a default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit.

(emphasis mine)

And since the friend function template declaration that you've provided specifies default template argument(s) and is not a definition, the program is ill-formed. Thus, gcc and clang and right in rejecting the program.

To solve this, you can provide a definition by adding the body of the friend function template. Demo.


Here is the msvc bug report:

Invalid Friend function template operator== compiles with msvc

Jason
  • 36,170
  • 5
  • 26
  • 60