直到C ++的C ++ 20标准,当我们想定义一个使用模板类的一些私有成员的类外运算符时,我们将使用类似于以下的构造:
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开始,我们可以省略类外声明,因此也可以省略前向声明,因此我们可以避免:
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中的错误。
我提交了关于gcc的bugzilla 的错误报告
"c string" == Foo<std::string>("foo")
))。