c++ - जीसीसी त्रुटि जब डिफ़ॉल्ट केस और लैम्ब्डा फ़ंक्शन के साथ स्विच स्टेटमेंट का उपयोग करते हैं




gcc lambda (3)

मुझे समझ में नहीं आता कि यह कोड क्यों है

#include <iostream>

class A {
    public:


    void foo(){
        char g = 'm';
        switch(g){
            case 'g':
                auto f = [](){std::printf("hello world\n");};
                f();
                break;
//            default:
//                std::printf("go to hell\n");
//                break;
        }
    };
};



int main(int iargc, char *iargv[]){
    A a;
    a.foo();
}

संकलित (और काम करता है) ठीक है, जबकि जब डिफ़ॉल्ट स्टेटमेंट को कम किया जाता है

#include <iostream>

class A {
    public:


    void foo(){
        char g = 'm';
        switch(g){
            case 'g':
                auto f = [](){std::printf("hello world\n");};
                f();
                break;
            default:
                std::printf("go to hell\n");
                break;
        }
    };
};



int main(int iargc, char *iargv[]){
    A a;
    a.foo();
}

मुझे निम्न त्रुटि संदेश देता है

test.cpp:15:13: error: jump to case label [-fpermissive]
         default:
         ^
test.cpp:12:22: error:   crosses initialization of A::foo()::__lambda0 f
             auto f = [](){std::printf("hello world\n");};

मैं एक डिफ़ॉल्ट स्टेटमेंट का उपयोग कर सकता हूं, अगर मैं लैम्ब्डा फंक्शन को कमेंट करता हूं।

मैं जीसीसी 4.8.5 का उपयोग कर रहा हूँ।


आपके कोड को ब्रेसिज़ के बीच लपेटें या इसे एक ही ब्लॉक के रूप में माना जाता है

डिफॉल्ट के लिए जाप करते हुए चर घोषणा को छोड़ता है।

case 'g':
    {
                auto f = [](){std::printf("hello world\n");};
                f();
                break;
    }

आपको अपने case 'g' शरीर को ब्रेसिज़ में शामिल करने की आवश्यकता है। यह लैम्ब्डा प्रति के कारण नहीं है, बल्कि एक केस बयान में किसी भी नए चर के निर्माण के कारण।

डिफ़ॉल्ट के बिना मुझे लगता है कि यह शिकायत नहीं करता है क्योंकि केवल एक स्थान है जहां निष्पादन हो सकता है। लेकिन डिफ़ॉल्ट और कोई ब्रेसिज़ के साथ, आपके पास कोई समस्या है क्योंकि f का दायरा default कोड तक फैला हुआ है लेकिन इसे वहां आरंभ नहीं किया जाएगा


switch(g){
  case 'g':
    auto f = [](){std::printf("hello world\n");};
    f();
    break;
  default:
    std::printf("go to hell\n");
    break;
}

एक switch किसी लेबल पर नियंत्रण स्थानांतरित करता है ये सभी लेबल स्विच स्टेटमेंट द्वारा शुरू किए गए एकल ब्लॉक में हैं।

मानक (N4296 §6.7 / 3) कहते हैं (जोर मेरा):

[नियंत्रण] को एक ब्लॉक में स्थानांतरित करना संभव है, लेकिन ऐसा नहीं है कि प्रारंभिक रूप से घोषणाओं को बायपास करता है एक ऐसा कार्यक्रम जो एक बिंदु से कूदता है जहां स्वत: भंडारण की अवधि के साथ एक चर एक बिंदु पर नहीं है, जहां यह दायरे में है, जब तक कि वेरिएबल के स्केलर प्रकार नहीं होते हैं, एक तुच्छ डिफ़ॉल्ट कन्स्ट्रक्टर और तुच्छ डिस्ट्रिक्टर के साथ वर्ग प्रकार इन प्रकारों में से किसी एक का सीवी-योग्य संस्करण, या पूर्ववर्ती प्रकारों में से एक की एक सरणी और प्रारंभकर्ता के बिना घोषित किया गया है

इस प्रकार, क्योंकि सीधे default लेबल पर नियंत्रण स्थानांतरित करना संभव है, लैम्ब्डा f (जो कि तुच्छ नहीं है) के घोषणापत्र और आरंभीकरण से पहले, आपका प्रोग्राम खराब तरीके से बना हुआ है और कंपाइलर द्वारा सही तरीके से खारिज कर दिया गया है।





switch-statement