निम्नलिखित कोड 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/8GG8478
क्लच-ट्रंक के साथ त्रुटि और -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
और scalars, जो वापसी (की अभिव्यक्ति) की एक सरणी bool
(जो तब तत्व के लिहाज से पहुँचा जा सकता है, या अन्यथा उपयोग किया जाता है )। उदाहरण के लिए,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
मेरे ऊपर के उदाहरण के विपरीत यह gcc-trunk के साथ भी विफल होता है: https://godbolt.org/z/RWktKs । मैं इसे अभी तक एक गैर-ईजेन उदाहरण में कम करने में कामयाब नहीं हुआ हूं, जो कि क्लैंग-ट्रंक और जीसीसी-ट्रंक दोनों में विफल रहता है (शीर्ष पर उदाहरण काफी सरल है)।
संबंधित मुद्दे की रिपोर्ट: https://gitlab.com/libeigen/eigen/issues/1833
मेरा वास्तविक प्रश्न: क्या यह वास्तव में C ++ 20 में एक ब्रेकिंग परिवर्तन है (और मेटा-ऑब्जेक्ट्स को वापस करने के लिए तुलना ऑपरेटरों को अधिभारित करने की संभावना है), या क्या यह संभवतः क्लैंग / जीसीसी में प्रतिगमन है?