จนถึงมาตรฐาน 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 เราสามารถละเว้นการประกาศนอกคลาสดังนั้นจึงมีการประกาศล่วงหน้าดังนั้นเราจึงสามารถออกไปได้ด้วย:
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 ++ ก่อนหน้านี้
ในขณะที่มันถูกชี้ให้เห็นในความคิดเห็นเสียงดังกราวไม่ยอมรับรหัสนี้ที่นำเสนอในการสาธิตซึ่งแสดงให้เห็นว่านี่อาจเป็นข้อผิดพลาดใน gcc
ฉันได้ยื่นรายงานข้อผิดพลาดใน Bugzilla ของ gcc
"c string" == Foo<std::string>("foo")
))