मैं एक कोड का टुकड़ा है कि संकलित करता है तथा बजना ++ 4 (और ट्रंक) में ठीक से काम करता लेकिन जी ++ 7 (और ट्रंक) में संकलित करने के लिए विफल रहता है की खोज की है बनाम। के मैं निम्नलिखित struct
प्रकार है मान लेते हैं:ओवरलोडिंग structs - जीसीसी बजना
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
मैं एक अधिभार सेट lambdas जो a
स्पष्ट रूप से हैंडल से बाहर बनाना चाहते हैं, जबकि b
और c
एक सामान्य लैम्ब्डा एक auto
पैरामीटर का उपयोग करने के साथ "पकड़ा" कर रहे हैं:
auto ol = overload([](a x) { x.foo(); },
[](auto x){ x.bar(); })
जब मैं आह्वान ol(a{})
:
क्लैंग ++ संकलित और अपेक्षित व्यवहार करता है:
a
पहले लैम्ब्डा "मैचों" से मेल खाता है, जबकिb
औरc
दूसरे से मेल खाता है।जी ++ निम्न त्रुटि के साथ, संकलन करने में विफल रहता है:
error: 'struct a' has no member named 'bar' [](auto x){ x.bar(); }; ~~^~~
ऐसा लगता है कि संकलक दूसरा लैम्ब्डा भले ही पहले एक एक तरह से बेहतर मुकाबला नहीं है का दृष्टांत की कोशिश करता है। उम्मीद है कि यह एक बग है, क्योंकि यह मेरे लिए अनजान लगता है।
नोट दोनों compilers ठीक से काम करने के बजाय लैम्ब्डा भाव मैं कुछ पुराने जमाने struct
उदाहरणों का उपयोग करते हैं:
struct s0
{
auto operator()(a x) const { x.foo(); }
};
struct s1
{
template <typename T>
auto operator()(T x) const { x.bar(); }
};
auto os = overload(s0{}, s1{});
os(a{}); // OK!
मैं lambdas मोटे तौर पर s0
के बराबर होने की अपेक्षा करेंगे और s1
, तो यह और भी आश्चर्यजनक है। यहाँ
template <typename... Fs>
struct overloader : Fs...
{
template <typename... FFwds>
overloader(FFwds&&... fs) : Fs{std::forward<FFwds>(fs)}...
{
}
using Fs::operator()...;
};
template <typename... Fs>
auto overload(Fs&&... fs)
{
return overloader<std::decay_t<Fs>...>{std::forward<Fs>(fs)...};
}
और compilers के बीच अलग व्यवहार दिखा रहा है, एक live example on gcc.godbolt.org
है:
इस तरह से मैं अधिभार सेट का निर्माण कर रहा हूँ है।
क्या यह एक g ++ बग है? या क्या मानक में कुछ ऐसा है जो इस स्थिति में struct
उदाहरणों से लैम्ब्स अलग तरीके से व्यवहार करता है?
हू, जब <<का उपयोग कर रहा था ...मानक दर्ज करें? सी ++ 17? –
@ नियरफ्राइडमैन यिप, सी ++ 17 में, [पी 01 9 5] (http://wg21.link/p0195) – Barry
के अलावा धन्यवाद: 'ओवरलोड' के लिए तर्क के रूप में फ़ंक्शन पॉइंटर्स लेने में सक्षम होना अच्छा है। ऐसा करने के लिए, ': Fs ...' को ': some_magic ...' के साथ बदलें, जहां 'some_magic' फ़ंक्शन पॉइंटर्स का पता लगाता है और इसे संग्रहीत करने वाले वर्ग में मानचित्र करता है, और बाकी सब कुछ अकेले छोड़ देता है। (लेकिन हो सकता है कि यह ओवरलोड एक सरलीकृत एमसीवीई है, जिस स्थिति में इसे अनदेखा किया जाता है) –
Yakk