Bis zum C ++ 20-Standard von C ++, als wir einen Operator außerhalb der Klasse definieren wollten, der einige private Mitglieder einer Vorlagenklasse verwendet, verwendeten wir ein ähnliches Konstrukt:
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;
}
Seit C ++ 20 können wir jedoch die Deklaration außerhalb der Klasse und damit auch die Vorwärtsdeklaration weglassen, sodass wir mit nur:
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;
}
Meine Frage ist nun, welcher Teil von C ++ 20 erlaubt es uns, dies zu tun? Und warum war dies in früheren C ++ - Standards nicht möglich?
Wie in den Kommentaren erwähnt, akzeptiert clang diesen in der Demo dargestellten Code nicht, was darauf hindeutet, dass dies tatsächlich ein Fehler in gcc ist.
Ich habe einen Fehlerbericht über gccs Bugzilla eingereicht
"c string" == Foo<std::string>("foo")
)).