Aż do standardu C ++ 20 C ++, gdy chcieliśmy zdefiniować operatora spoza klasy, który korzysta z niektórych prywatnych członków klasy szablonu, używamy konstrukcji podobnej do tej:
template <typename T>
class Foo;
template <typename T>
constexpr bool operator==(T lhs, const Foo<T>& rhs);
template <typename T>
class Foo {
public:
constexpr Foo(T k) : mK(k) {}
constexpr friend bool operator==<T>(T lhs, const Foo& rhs);
private:
T mK;
};
template <typename T>
constexpr bool operator==(T lhs, const Foo<T>& rhs) {
return lhs == rhs.mK;
}
int main() {
return 1 == Foo<int>(1) ? 0 : 1;
}
Od wersji C ++ 20 możemy jednak pominąć deklarację spoza klasy, a więc także deklarację forward, dzięki czemu możemy uniknąć:
template <typename T>
class Foo {
public:
constexpr Foo(T k) : mK(k) {}
constexpr friend bool operator==<T>(T lhs, const Foo& rhs);
private:
T mK;
};
template <typename T>
constexpr bool operator==(T lhs, const Foo<T>& rhs) {
return lhs == rhs.mK;
}
Moje pytanie brzmi: jaka część C ++ 20 pozwala nam to zrobić? I dlaczego nie było to możliwe we wcześniejszych standardach C ++?
Jak wskazano w komentarzach, clang nie akceptuje tego kodu przedstawionego w wersji demo, co sugeruje, że może to być rzeczywiście błąd w gcc.
I złożył raport o błędzie na Bugzilla GCC
"c string" == Foo<std::string>("foo")
)).