Cho đến tiêu chuẩn C ++ 20 của C ++, khi chúng tôi muốn xác định toán tử ngoài lớp sử dụng một số thành viên riêng của lớp mẫu, chúng tôi sẽ sử dụng cấu trúc tương tự như sau:
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;
}
Tuy nhiên, vì C ++ 20, chúng ta có thể bỏ qua khai báo ngoài lớp, do đó cũng là khai báo chuyển tiếp, vì vậy chúng ta có thể thoát khỏi chỉ với:
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;
}
Bây giờ, câu hỏi của tôi là, phần nào của C ++ 20 cho phép chúng ta làm như vậy? Và tại sao điều này không thể xảy ra trong các tiêu chuẩn C ++ trước đó?
Như đã chỉ ra trong các bình luận, clang không chấp nhận mã này được trình bày trong bản demo, điều này cho thấy đây thực sự có thể là một lỗi trong gcc.
Tôi đã nộp báo cáo lỗi về bugzilla của gcc
"c string" == Foo<std::string>("foo")
)).