Вплоть до C ++ 20 стандарта C ++, когда мы хотели определить внеклассный оператор, который использует некоторые закрытые члены шаблонного класса, мы использовали конструкцию, подобную этой:
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;
}
Начиная с C ++ 20, однако, мы можем опустить объявление вне класса, таким образом, также и объявление forward, так что мы можем обойтись просто:
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;
}
Теперь мой вопрос: какая часть C ++ 20 позволяет нам это делать? И почему это не было возможно в более ранних стандартах C ++?
Как было отмечено в комментариях, clang не принимает этот код, представленный в демоверсии, что предполагает, что это может быть ошибка в gcc.
Я отправил отчет об ошибке на bugzilla gcc
"c string" == Foo<std::string>("foo")
)).