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.
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