Я думаю, сообщение об ошибке, которое вы получили, может вводить в заблуждение или, по крайней мере, сбивать с толку.Проблема с вашим кодом заключается в неправильном объявлении friend
.
Объявление оператора внутри шаблонной структуры как friend
делает его свободной функцией, так же как operator<
в вашем примере, следовательно,два параметра вместо одного параметра, как в случае operator!=
, как вы объявили в своем примере.Если бы вы объявили operator<
другом struct A
, правильный способ сделать это будет:
template <typename X>
friend constexpr bool operator< (const A<X>& l, const A<X>& r);
То же самое относится и к operator==
.Правильным объявлением будет:
template <typename X>
friend constexpr bool operator== (const A<X>& l, const A<X>& r)
{
return l.Value == r.Value;
}
т.е. WITH template <typename X>
, которое вы пропустили в своем проблемном примере и, следовательно, не скомпилировали.Ваше оригинальное объявление operator==
не приведет к правильному оператору функции без друзей для struct A
.
Полный список кода, включая исправление, будет следующим:
template <typename T>
struct A
{
T Value;
// no error anymore
template <typename X>
friend constexpr bool operator== (const A<X>& l, const A<X>& r)
{
return l.Value == r.Value;
}
// ok
constexpr bool operator!= (const A& r) const
{
return Value != r.Value;
}
};
Вы также можете объявить это следующим образом
template <typename T>
friend constexpr bool operator== (const A<T>& l, const A<T>& r)
с T
вместо X
, но на самом деле это то же самое, поскольку внутренний T
переопределяет внешний T
.