2017-03-04 9 views
19

यह an earlier question about why I can't use a brace-enclosed initializer as an argument to operator+ पर एक फॉलो-अप है, जिसे this earlier question on the subject पर देखकर हल किया गया था।मैं ऑपरेटर + = के दाहिने हाथ पर प्रारंभकर्ता सूचियों का उपयोग क्यों कर सकता हूं लेकिन ऑपरेटर + नहीं?

पर विचार करें निम्नलिखित सी ++ कोड है, जो आप try live at ideone.com कर सकते हैं:

#include <iostream> 
#include <initializer_list> 
using namespace std; 

struct AddInitializerList { 
    void operator+= (initializer_list<int> values) { 
     // Do nothing 
    } 

    void operator+ (initializer_list<int> values) { 
     // Do nothing 
    } 
}; 

int main() { 
    AddInitializerList adder; 
    adder += {1, 2, 3}; // Totally legit 
    adder + {1, 2, 3}; // Not okay! 

    return 0; 
} 

main में लाइन लगा कर संलग्न प्रारंभकर्ता सूची के साथ operator+ का उपयोग करता है संकलन नहीं करता है (और है कि पहले सवाल पूछने के बाद, मैं अब पता है कि यह क्यों है)। हालांकि, मैं उलझन में हूं कि opeartor+= का उपयोग main में वास्तव में ठीक क्यों संकलित करता है।

मैं उलझन में हूं कि मैं += को अधिभार क्यों अधिभारित कर सकता हूं और यह ठीक काम करता है, जबकि + ओवरलोडिंग यहां काम नहीं कर रहा है। क्या मानक में कोई विशेष प्रावधान है जो += ऑपरेटर के संदर्भ में ब्रेस-संलग्न प्रारंभकर्ताओं को अनुमति देता है लेकिन + ऑपरेटर नहीं? या यह सिर्फ एक अजीब कंपाइलर quirk है?

+0

आपने अपना कंपाइलर निर्दिष्ट नहीं किया है, लेकिन मैं इसे जीसीसी 6.3.1 के साथ विफल करता हूं, जो मुझे "त्रुटि: अपेक्षित प्राथमिक अभिव्यक्ति 'से पहले {{टोकन" के साथ छाल देता है। –

+0

मुझे लगता है कि घुंघराले ब्रेसिज़ सभी असाइनमेंट ऑपरेटरों के लिए समर्थित है। –

+1

और 'योजक + प्रारंभकर्ता_सूची {1, 2, 3};' ठीक काम करता है। –

उत्तर

21

यह this question के जवाब में स्पष्ट किया गया है (जो आपके द्वारा लिंक किए गए प्रश्न से जुड़ा हुआ है)।

भाषा व्याकरण केवल कुछ व्याकरणिक संदर्भों में एक ब्रैस्ड सूची की अनुमति देता है, न कि मनमाने ढंग से अभिव्यक्ति के स्थान पर। उस सूची में असाइनमेंट ऑपरेटर के दाहिने हाथ शामिल हैं, लेकिन आम तौर पर ऑपरेटर के दाएं हाथ नहीं हैं।

+= एक असाइनमेंट ऑपरेटर है, + नहीं है।

काम भाव के लिए व्याकरण है:

 
    assignment-expression: 
    conditional-expression 
    logical-or-expression assignment-operator initializer-clause 
    throw-expression 
    assignment-operator: one of 
     = *= *= /= %= += -= >>= <<= &= ^= |= 

+0

@NeilButterworth जो Q/A में शामिल है I –

+0

से जुड़ा हुआ है, यह निश्चित रूप से चीजों को समझाएगा। धन्यवाद! – templatetypedef

+0

मुझे नहीं लगता कि यह एक जवाब है। सवाल यह है कि व्याकरण '+' 'के लिए ब्रेस इनिट सूची क्यों देता है लेकिन' + 'के लिए नहीं। विशेष व्याकरण नियम को सूचीबद्ध करते हुए सिर्फ यह कहता है कि व्याकरण की अनुमति के बारे में ओपी गलत नहीं है। –

7

+= ऑपरेटर यौगिक असाइनमेंट है। मानक स्पष्ट रूप से कार्य की दाएँ हाथ की ओर पर प्रारंभकर्ता सूचियों परमिट: सभी असाइनमेंट के बारे में

§8.5.4/1 [...] Note: List-initialization can be used

...

— on the right-hand side of an assignment (5.17)

§5.17 वार्ता, यौगिक भी शामिल होते हैं:

assignment-expression:
- conditional-expression
- logical-or-expression assignment-operator initializer-clause
- throw-expression

assignment-operator: one of
= *= /= %= += -= >>= <<= &= ˆ= |=

9

सी ++ 14 §5.17/9:

A braced-init-list may appear on the right-hand side of

  • an assignment to a scalar, in which case the initializer list shall have at most a single element. The meaning of x={v} , where T is the scalar type of the expression x , is that of x=T{v} . The meaning of x={} is x=T{} .
  • an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3).

इस के माध्यम से एक+= अपने $ 5.7/7 तुल्यता पर लागू होता है =+बी ( को छोड़कर += के लिए केवल एक बार मूल्यांकन किया जाता है)। एमएम द्वारा एक टिप्पणी के कारण, एक और तरीका रखें, अंतर्निहित ऑपरेटरों += के समतुल्यता के कारण एक असाइनमेंट ऑपरेटर के रूप में माना जाता है, न कि एक विशेष अद्यतन ऑपरेटर। इसलिए “ असाइनमेंट ” से ऊपर उद्धृत पाठ += पर लागू होता है।

+2

ऐसा इसलिए है क्योंकि 'ए + = बी' असाइनमेंट अभिव्यक्तियों के लिए व्याकरण से मेल खाता है, न कि समानता के कारण 'ए = ए + बी' (जो अधिभारित ऑपरेटरों के मामले में भी सत्य नहीं है)। 5.17/7 केवल गैर-अधिभारित मामले को संदर्भित करता है; खंड 5 –

+0

@ एमएम की शुरुआत में बिंदु 3 देखें। आप सही हैं, और यह एक मामूली अवलोकन है। आप यह दावा करके और अधिक रोचक बना सकते हैं कि मानक $ 5 में एक दोष है, जहां यह उपयोगकर्ता परिभाषित '+ =' को कवर करने में विफल रहता है। –

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

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