c++ - tutorial - तिर्यक अभिव्यक्ति में अल्पविराम के साथ भ्रम




the c++ programming language (2)

ऐसा इसलिए है क्योंकि C ++ दूसरे अल्पविराम को अल्पविराम ऑपरेटर नहीं मानता है :

विभिन्न अल्पविराम से अलग सूचियों में अल्पविराम, जैसे कि फ़ंक्शन तर्क सूचियाँ f(a, b, c) और initializer सूचियाँ int a[] = {1,2,3} , वह अल्पविराम संचालक नहीं है।

जहां तक ​​पहले अल्पविराम का सवाल है, सी ++ के पास इसे कोमा संचालक के रूप में मानने के अलावा और कोई विकल्प नहीं है। अन्यथा, तोता अमान्य होगा।

यह देखने का एक सरल तरीका यह सोचना है कि जैसे ही सी ++ पार्सर पाता है ? संदर्भ में जहां अल्पविराम विभाजकों की अनुमति है, यह मिलान के लिए दिखता है : अभिव्यक्ति के पहले भाग को पूरा करने के लिए, और फिर दूसरी अभिव्यक्ति को पूरा करने के लिए जितना आवश्यक हो उतना कम मेल खाता है। दूसरी अल्पविराम को एक ऑपरेटर के रूप में नहीं माना जाएगा भले ही आप दो-तर्क अधिभार को हटा दें।

मुझे आज निम्नलिखित दिलचस्प कोड मिला:

SomeFunction(some_bool_variable ? 12.f, 50.f : 50.f, 12.f)

मैंने व्यवहार को पुन: पेश करने के लिए एक छोटा सा नमूना बनाया:

class Vector3f
{
public:
    Vector3f(float val)
    {
        std::cout << "vector constructor: " << val << '\n';
    }
};

void SetSize(Vector3f v)
{
    std::cout << "SetSize single param\n";
}

void SetSize(float w, float h, float d=0)
{
    std::cout << "SetSize multi param: " << w << ", " << h << ", " << d << '\n';
}

int main()
{
    SetSize(true ? 12.f, 50.f : 50.f, 12.f);
    SetSize(false ? 12.f, 50.f : 50.f, 12.f);
}

( लाइव नमूना )

उपरोक्त कोड चलाने से मुझे जो परिणाम मिलता है वह है:

clang++ -std=c++14 -O2 -Wall -pedantic -lboost_system -lboost_filesystem -pthread main.cpp && ./a.out
main.cpp:29:20: warning: expression result unused [-Wunused-value]
    SetSize(true ? 12.f, 50.f : 50.f, 12.f);
                   ^~~~
main.cpp:30:21: warning: expression result unused [-Wunused-value]
    SetSize(false ? 12.f, 50.f : 50.f, 12.f);
                    ^~~~
2 warnings generated.
SetSize multi param: 50, 12, 0
SetSize multi param: 50, 12, 0

मैं दोनों मामलों में उम्मीद कर रहा था कि एक एकल पैरामीटर SetSize(float) को पारित किया जाएगा। हालाँकि, दो मानदंड पारित किए गए हैं, जो मुझे बेहद भ्रामक लगते हैं (विशेषकर चूंकि टर्नरी का कॉमा पर पूर्वग्रह है, इसलिए मैंने माना कि कॉमा इस मामले में फ़ंक्शन तर्कों का परिसीमन नहीं कर रहा है)। उदाहरण के लिए, यदि true का उपयोग किया true , तो टर्नरी का परिणाम 12.f, 50.f में होना चाहिए। इस अभिव्यक्ति में, अल्पविराम के बाईं ओर का मान गिरा / अनदेखा हो जाता है, इसलिए मुझे अंतिम परिणाम की उम्मीद होगी:

SetSize(50.f);

भ्रम का दूसरा हिस्सा यह है कि क्या हम टर्नरी में true या false उपयोग करते हैं, वही 2 मान फ़ंक्शन में पास होते हैं। true मामला h=12, w=50 होना चाहिए h=12, w=50 मुझे लगता है ...

मैं देख रहा हूं कि कंपाइलर मुझे किसी चीज के बारे में आगाह करने की कोशिश कर रहा है, लेकिन मैं यह नहीं समझ सकता कि क्या हो रहा है। क्या कोई इस तर्क का विरोध कर सकता है और परिणाम को चरणबद्ध तरीके से समझा सकता है?


जबकि टर्नरी ऑपरेटर का दूसरा भाग स्वयं निहित है, तीसरा भाग नहीं है। व्याकरण इस प्रकार है:

सशर्त-अभिव्यक्ति :

तार्किक या अभिव्यक्ति

तार्किक-या-अभिव्यक्ति? अभिव्यक्ति: असाइनमेंट-एक्सप्रेशन

तो आपका फ़ंक्शन कॉल प्रभावी रूप से यह है:

SetSize((true ? (12.f, 50.f): 50.f), 12.f)

तो त्रैमासिक अभिव्यक्ति true ? (12.f, 50.f): 50.f true ? (12.f, 50.f): 50.f फ़ंक्शन के पहले पैरामीटर के रूप में मूल्यांकन किया जाता है। फिर 12.f को दूसरे मूल्य के रूप में पारित किया जाता है। इस मामले में अल्पविराम अल्पविराम ऑपरेटर नहीं है , लेकिन फ़ंक्शन पैरामीटर विभाजक है।

C ++ मानक के खंड 5.18 से:

2 संदर्भों में जहां अल्पविराम को एक विशेष अर्थ दिया जाता है, उदाहरण के लिए: कार्यों की दलीलों की सूची (5.2.2) और प्रारंभिकों की सूची (8.5) - अंतिम उदाहरण ] जैसा कि खंड 5 में वर्णित अल्पविराम ऑपरेटर केवल कोष्ठक में दिखाई दे सकता है। [ उदाहरण:

f(a, (t=3, t+2), c);

तीन तर्क हैं, जिनमें से दूसरे का मान 5 है। - अंतिम उदाहरण ]

यदि आप चाहते हैं कि पिछले दो सबएक्सप्रेस को एक साथ समूहीकृत किया जाए, तो आपको कोष्ठक जोड़ना होगा:

SetSize(true ? 12.f, 50.f : (50.f, 12.f));
SetSize(false ? 12.f, 50.f : (50.f, 12.f));

अब आपके पास अल्पविराम ऑपरेटर है और SetSize का एकल तर्क संस्करण कहलाता है।





c++