2017-06-21 7 views
7

[conv]/4 से असहमत:[expr.unary.op]/9 यह इंगित करता है कि `ऑपरेटर!()` नीचे दिए गए प्रकार ए पर लागू नहीं किया जा सका। लेकिन compilers कि

कुछ भाषा निर्माणों की आवश्यकता है कि एक अभिव्यक्ति एक बूलियन मान के लिए परिवर्तित किया जा। एक अभिव्यक्ति e इस तरह के एक संदर्भ में प्रदर्शित होने कहा प्रासंगिक रूप bool में बदला और अच्छी तरह से बनाई है, तो और केवल तभी घोषणा bool t(e); अच्छी तरह से बनाई है, कुछ का आविष्कार किया अस्थायी चर t (11.6) के लिए माना जाता है।

अब नीचे स्निपेट पर विचार करें। यह संकलित नहीं करता है, न तो clang, GCC या VS में।

struct A{ bool operator!() { return true; } }; 
int main(){ 
    A a; 
    bool t(a); 
} 

इस प्रकार, से [रूपा]/4 हम निष्कर्ष है कि प्रकार Aप्रासंगिक रूप bool में परिवर्तित नहीं है।

[expr.unary.op]/9:

तार्किक निषेध ऑपरेटर ! के संकार्य प्रासंगिक रूप bool में बदल जाती है (खण्ड 7); इसका मान true है यदि परिवर्तित ऑपरेंड false और false अन्यथा है। परिणाम का प्रकार bool है।

अनुच्छेद के मेरे समझ से ऊपर है कि तार्किक निषेध ऑपरेटर ! के संकार्य प्रासंगिक रूप bool परिवर्तित किया जाना चाहिए है। हमने अभी निष्कर्ष निकाला है कि A संदर्भित रूप से bool में परिवर्तित हो गया है। इसलिए, [expr.unary.op]/9 से, हम कह सकते हैं कि निम्न कोड संकलित नहीं होना चाहिए। लेकिन यह clang, GCC और VS में करता है।

struct A{ bool operator!() { return true; } }; 
int main(){ 
    A a; 
    bool t = !a; 
} 

मुझे क्या याद आ रही है?

+3

यह एक तार्किक अस्वीकरण ऑपरेटर नहीं है, इसका सदस्य 'ए :: ऑपरेटर!' कार्य करता है, वैसे भी मेरा अनुमान है। मेरा मानना ​​है कि यह 'ऑपरेटर' के साथ एक ही बात है, कॉमा ऑपरेटर के पास ओवरलोड के बिना भी एक अंतर्निहित अर्थ है, लेकिन एक अधिभार –

+0

के साथ प्रदान किए जाने पर अच्छी तरह से परिभाषित किया गया है 'बूल टी (ए);' टू 'बूल टी (ए); 'आपके पहले उदाहरण में। कंपाइलर अनुमान लगा सकता है कि इसे 'ऑपरेटर' लागू करने की आवश्यकता है। –

+4

[खंड \ [expr \] ऑपरेटर के प्रभाव को परिभाषित करता है जब उन प्रकारों पर लागू होता है जिनके लिए उन्हें ओवरलोड नहीं किया गया है।] (Http://eel.is/c++draft/expr#3.sentence-1) – cpplearner

उत्तर

7

[expr] एक पूरी निर्मित ऑपरेटरों पर लागू होता है के रूप में: जब प्रकार जिसके लिए वे अतिभारित नहीं किया गया है करने के लिए लागू

खण्ड [expr] ऑपरेटरों के प्रभाव को परिभाषित करता है।

[expr.unary.op] में परिभाषा बस निर्मितoperator! की परिभाषा है। साथ ही, [over.match.oper] का वर्णन करता है अतिभारित ऑपरेटरों को देखने के लिए कैसे: एक प्रकार जिसका सीवी-अयोग्य संस्करण, टी 1 है [...], उम्मीदवार कार्यों के तीन सेट, नामित सदस्य का एक संकार्य साथ

एक एकल ऑपरेटर @ के लिए उम्मीदवार, गैर-सदस्य उम्मीदवार और अंतर्निहित उम्मीदवार निम्नानुसार हैं: [...]

!a के लिए, आप दो उम्मीदवारों होगा: अपने अधिभार A::operator!() और निर्मित [over.built] में परिभाषित:

वहाँ भी फार्म के उम्मीदवार ऑपरेटर कार्यों मौजूद

bool operator!(bool); 

ओवरलोड रिज़ॉल्यूशन द्वारा निर्मित अंतर्निहित के लिए, प्रकार को संदर्भित रूप से bool में परिवर्तित करना होगा और डैगर; आपके तर्क के अनुसार सुझाव देता है। हालांकि, यह उम्मीदवार व्यवहार्य नहीं है - लेकिन अधिभारित सदस्य ऑपरेटर है।


और डैगर;T.C. जो इंगित करता है कि एक प्रकार है कि प्रासंगिक रूप bool के लिए परिवर्तनीय अब भी है एक शब्दों के मुद्दे के कारण निर्मित operator! उपयोग नहीं करना चाहिए cwg issue 1919 उनका कहना है, हमेशा की तरह इसके बारे में शीर्ष पर है। हालांकि, दोनों जीसीसी और क्लैंग इसे अनुमति देते हैं (जो हम सभी बनना चाहते हैं, शायद)।

+0

लेकिन ध्यान दें [मूल मुद्दा 1 9 1 9] (https://wg21.link/CWG1919)। –

+1

@ टी.सी. आप कभी आश्चर्यचकित नहीं रहना। इसके अलावा जोहान्स ने स्पष्ट रूप से हर मूल मुद्दे को प्रस्तुत किया है। – Barry

संबंधित मुद्दे

 संबंधित मुद्दे