Fino allo standard C ++ 20 di C ++, quando volevamo definire un operatore fuori classe che utilizza alcuni membri privati di una classe template, useremmo un costrutto simile a questo:
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;
}
Dal C ++ 20, tuttavia, possiamo omettere la dichiarazione fuori classe, quindi anche la dichiarazione in avanti, in modo da poter fare a meno di:
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;
}
Ora, la mia domanda è: quale parte di C ++ 20 ci consente di farlo? E perché ciò non era possibile nei precedenti standard C ++?
Come è stato sottolineato nei commenti, clang non accetta questo codice presentato nella demo, il che suggerisce che questo potrebbe effettivamente essere un bug in gcc.
Ho presentato una segnalazione di bug sul bugzilla di gcc
"c string" == Foo<std::string>("foo")
)).