รหัสต่อไปนี้รวบรวมดีกับ clang-trunk ในโหมด c ++ 17 แต่แบ่งในโหมด c ++ 2a (c ++ 20 ที่กำลังมาถึง):
// Meta struct describing the result of a comparison
struct Meta {};
struct Foo {
Meta operator==(const Foo&) {return Meta{};}
Meta operator!=(const Foo&) {return Meta{};}
};
int main()
{
Meta res = (Foo{} != Foo{});
}
นอกจากนี้ยังรวบรวมการปรับด้วย gcc-trunk หรือ clang-9.0.0: https://godbolt.org/z/8GGT78
ข้อผิดพลาดกับ clang-trunk และ-std=c++2a
:
<source>:12:19: error: use of overloaded operator '!=' is ambiguous (with operand types 'Foo' and 'Foo')
Meta res = (f != g);
~ ^ ~
<source>:6:10: note: candidate function
Meta operator!=(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function
Meta operator==(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function (with reversed parameter order)
ผมเข้าใจว่า C ++ 20 จะทำให้มันเป็นไปได้เพียงเกินoperator==
และเรียบเรียงโดยอัตโนมัติจะสร้างโดยกวนผลมาจากการoperator!=
operator==
เท่าที่ฉันเข้าใจนี่ใช้ได้ผลตราบใดที่ประเภทการคืนเป็นbool
เท่านั้น
แหล่งที่มาของปัญหาคือว่าใน Eigen เราประกาศชุดประกอบ==
, !=
, <
... ระหว่างArray
วัตถุหรือArray
และสเกลาซึ่งผลตอบแทน (การแสดงออกของ) อาร์เรย์ของbool
(ซึ่งจากนั้นจะสามารถเข้าถึงองค์ประกอบฉลาดหรือนำไปใช้อย่างอื่น ) เช่น,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
ในทางตรงกันข้ามกับตัวอย่างของฉันข้างต้นนี้แม้จะล้มเหลวด้วย GCC-ลำต้น: https://godbolt.org/z/RWktKs ฉันยังไม่ได้จัดการเพื่อลดสิ่งนี้ให้เป็นตัวอย่างที่ไม่ใช่ของ Eigen ซึ่งล้มเหลวทั้งใน clang-trunk และ gcc-trunk (ตัวอย่างที่ด้านบนค่อนข้างง่าย)
รายงานปัญหาที่เกี่ยวข้อง: https://gitlab.com/libeigen/eigen/issues/1833
คำถามที่แท้จริงของฉัน: นี่คือการเปลี่ยนแปลงจริงใน C ++ 20 (และมีความเป็นไปได้ที่จะโอเวอร์โหลดตัวดำเนินการเปรียบเทียบเพื่อส่งคืน Meta-object) หรือมีแนวโน้มว่าจะถดถอยใน clang / gcc หรือไม่