Consider the following:
template<std::integral T>
class Integer {
T value;
template<std::integral T2>
friend class Integer;
public:
template<std::integral T2>
friend bool operator==(Integer<T> x, Integer<T2> y) {
return x.value == y.value;
}
};
the Integer class defines the friend operator== to compare other entities with different template parameters and declares the template Integer class as the friend class.
But when I compare two objects with different template parameters:
Integer<int> x;
Integer<long> y;
x == y;
Clang accepts it but GCC and MSVC reject it with:
<source>:11:25: error: 'long int Integer<long int>::value' is private within this context
11 | return x.value == y.value;
| ~~^~~~~
This surprised me a bit. In my opinion, it should be well-formed, because operator== is a friend of Integer<int>, and Integer<long> is a friend of Integer<int>, so operator== should also have permission to access the member of Integer<long>.
So Which compiler should I trust?
Update
This is CWG1699.