2015-10-12 8 views
9

मेरा प्रश्न स्थैतिक सदस्य प्रारंभकर्ताओं के लिए लैम्ब्डा स्कोप के बारे में है।स्थिर सदस्यों के प्रारंभकर्ता के लिए लैम्ब्डा स्कोप

#include <functional> 
#include <iostream> 

struct S { 
    static const std::function<void(void)> s_func; 
}; 

const std::function<void(void)> S::s_func = []() { 
    std::cout << "Hello from " << __PRETTY_FUNCTION__ << std::endl; 
}; 

int main(void) { 
    S::s_func(); 
    return 0; 
} 

4,8 से शुरू जीसीसी एस के दायरे में लैम्ब्डा परिभाषित करता है, तो कार्यक्रम कुछ इस तरह आउटपुट:

Hello from S::<lambda()> 

(जीसीसी-4.8.2 एक अलग परिभाषा है निम्न परीक्षण पर विचार करें __FUNCTION__ & सह मैक्रो के लिए, लेकिन फिर भी लैम्ब्डा अभी भी S भीतर परिभाषित किया गया है)

इस बीच जीसीसी-4.7 वैश्विक क्षेत्र में लैम्ब्डा परिभाषित करता है, तो प्रोग्राम outputs

Hello from <lambda()> 

शायद नए जीसीसी अधिक मानक-अनुरूप हैं। हालांकि मैं यह पूछना चाहता हूं कि मानक वास्तव में इस पहलू को निर्दिष्ट करता है या यह कार्यान्वयन-निर्भर हो सकता है।

अद्यतन: @ user5434961 के रूप में सुझाव दिया है कि सभी __FUNCTION__ -alike मैक्रो कार्यान्वयन निर्भर कर रहे हैं, तो यह उन्हें एक मानक अनुरूप परीक्षण में से बचने के लिए बेहतर है।

#include <functional> 
#include <iostream> 

struct S { 
    static const std::function<void(void)> s_func; 
private: 
    static const int s_field; 
}; 

const std::function<void(void)> S::s_func = []() { 
    std::cout << "Hello from S::s_func. S::s_field = " << S::s_field << std::endl; 
}; 

const int S::s_field = 1; 

int main(void) { 
    S::s_func(); 
    return 0; 
} 
+0

मुझे लगता है कि आपको अद्यतन उदाहरण में 'S :: s_field' को 's_field' में बदलना चाहिए? अन्यथा, मुझे लगता है कि यह हमेशा जो कुछ भी गुंजाइश है उसे संकलित करता है। – Lingxi

+0

ठीक है, चूंकि 'एस :: एस_फील्ड 'निजी है, इसलिए इसे वैश्विक दायरे से नहीं पहुंचा जा सकता है, इसलिए कोड जीसीसी -4.7 पर संकलन को तोड़ देता है वास्तव में – user3159253

+0

हां, हां। मैंने निजी चीज़ को नजरअंदाज कर दिया। – Lingxi

उत्तर

7

यह समस्या पहले, लेकिन मैं प्रासंगिक बग रिपोर्ट नहीं मिल सकता है उठाया गया: तो यहाँ उदाहरण जो अगर एक संकलक S दायरे के भीतर इस तरह के lambdas परिभाषित करता है और अन्यथा संकलन टूट जाता है संकलित किया जा सकता है। एक एमएसवीसी बग रिपोर्ट के लिए broken link यहां दिया गया है जिसे माना जाता है (यह अभी भी 2015 में तय नहीं है: आप इसे rise4fun पर परीक्षण कर सकते हैं)। हालांकि इसे जीसीसी के लिए कहीं 4.7 और 4.8 के बीच तय किया गया है। प्रासंगिक एक बग के रूप में इस का बैकअप लेने के लिए इस्तेमाल किया standardese है:

[C++ 11, 9.4.2/2] एक static डेटा सदस्य के डी फाई nition में प्रारंभकर्ता अभिव्यक्ति अपने वर्ग के दायरे में है ।

[सी ++ 11, 5.1.2/2] एक लैम्ब्डा-अभिव्यक्ति के मूल्यांकन का परिणाम अस्थायी अस्थायी (12.2) में होता है। इस अस्थायी को बंद वस्तु कहा जाता है। एक लैम्ब्डा-अभिव्यक्ति एक अनियमित ऑपरेंड (क्लॉज 5) में दिखाई नहीं देगी।

[C++ 11, 5.1.2/3] लैम्ब्डा अभिव्यक्ति के प्रकार (जो भी बंद वस्तु के प्रकार है) एक अद्वितीय, अनाम गैर संघ वर्ग प्रकार है - बंद बुलाया प्रकार - जिनके गुण नीचे वर्णित हैं। यह वर्ग प्रकार कुल नहीं है (8.5.1)। बंदरगाह प्रकार को सबसे छोटे ब्लॉक स्कोप, वर्ग स्कोप, या नेमस्पेस स्कोप में घोषित किया गया है कि में संबंधित लैम्ब्डा-अभिव्यक्ति शामिल है।

पहले

Why lambda in static initializer can't access private members of class in VC++2013?

C++11 lambdas can access my private members. Why?

Why is it not possible to use private method in a lambda?

4

मुझे लगता है कि यह वर्ग दायरे में होना चाहिए।(जोर मेरा) cppreference से उद्धरित:

लैम्ब्डा अभिव्यक्ति एक अनाम prvalue अस्थायी वस्तु अद्वितीय अनाम गैर संघ गैर सकल प्रकार, बंद प्रकार के रूप में जाना जाता है के , जो घोषित किया जाता है (ADL के प्रयोजनों के लिए निर्माण करती है) सबसे छोटे ब्लॉक स्कोप, क्लास स्कोप, या नेमस्पेस स्कोप में जिसमें लैम्ब्डा अभिव्यक्ति शामिल है।

आउट-ऑफ-लाइन S::s_func की परिभाषा में, आप S के दायरे समय S:: का सामना करना पड़ा है में दर्ज करें। तो, लैम्ब्डा अभिव्यक्ति S के वर्ग दायरे में निहित है। जैसा कि निकट प्रकार S का सदस्य है, S के निजी सदस्यों तक पहुंच प्रदान की जाती है।

+0

समान रूप से सहायक उत्तरों के लिए आप और @ user5434961 दोनों का धन्यवाद। मैंने अपना जवाब स्वीकार कर लिया क्योंकि यह आपके से थोड़ा पहले था। – user3159253

+0

@ user3159253 आपका स्वागत है :) उपयोगकर्ता 5434961 का उत्तर मानक दस्तावेज़ का हवाला देते हुए मेरा से बेहतर है। – Lingxi

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