Jusqu'à la norme C ++ 20 de C ++, lorsque nous voulions définir un opérateur hors classe qui utilise certains membres privés d'une classe de modèle, nous utilisions une construction similaire à ceci:
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;
}
Depuis C ++ 20, cependant, nous pouvons omettre la déclaration hors classe, donc aussi la déclaration avant, afin que nous puissions nous contenter de:
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;
}
Maintenant, ma question est, quelle partie de C ++ 20 nous permet de le faire? Et pourquoi cela n'était-il pas possible dans les normes C ++ antérieures?
Comme cela a été souligné dans les commentaires, clang n'accepte pas ce code présenté dans la démo, ce qui suggère que cela pourrait en fait être un bogue dans gcc.
J'ai déposé un rapport de bug sur le bugzilla de gcc
"c string" == Foo<std::string>("foo")
)).