2012-12-14 21 views
6

g ++ 4.7 सरणी सदस्य प्रारंभिकरण का समर्थन करता है और मैंने इसके साथ खेलना शुरू कर दिया।उपयोगकर्ता परिभाषित प्रकारों के सरणी सदस्य प्रारंभिक

नीचे दिया गया कोड संकलित नहीं करता है।

struct A 
{ 
    A(int){}; 
    A(const A&) = delete; 
    A& operator=(const A&) = delete; 
    ~A(){}; 
}; 

struct B 
{ 
    B(): 
     a{{0},{1}} 
    {}; 
    A a[2]; 
}; 

B b; 

साथ जीसीसी 4.8 (प्री-रिलीज़) त्रुटि संदेश है:

n.cc: In constructor ‘B::B()’: 
n.cc:12:20: error: use of deleted function ‘A::A(const A&)’ 
      a{{0},{1}} 
      ^
n.cc:4:8: error: declared here 
     A(const A&) = delete; 
     ^

वहाँ इस कोड को काम करने के लिए कोई तरीका है? मैं ए के विनाशकों को आसानी से नहीं बदल सकता, मुझे सरणी को प्रारंभ करने के लिए एक चालक-निर्माता या प्रति-निर्माता की आवश्यकता होती है, लेकिन यह काउंटर-अंतर्ज्ञानी लगता है, क्योंकि मैं वास्तव में सभी जगहों पर निर्माण करना चाहता हूं।

यह काम करता है अगर मैं 2 सदस्यों और ए 1 में एक [2] विभाजित करता हूं, और उन्हें अलग से बना देता हूं। हालांकि यह फिश लग रहा है।

+0

':' एक कन्स्ट्रक्टर में प्रतिलिपि बनाने के लिए कॉपी कन्स्ट्रक्टर का उपयोग करता है, और आप इसे ए में हटा देते हैं जिससे आपको कोई त्रुटि मिलती है। –

उत्तर

2

Arrays समेकित हैं, और कुल प्रारंभिकरण हमेशा प्रति प्रारंभिकरण का उपयोग करता है। सी ++ 11 §8.5.1/1:

एक कुल एक सरणी या कोई उपयोगकर्ता द्वारा प्रदान की कंस्ट्रक्टर्स के साथ एक वर्ग, कोई ब्रेस या बराबर-प्रारंभकर्ता गैर के लिए रों है स्थैतिक डेटा सदस्य, कोई निजी या संरक्षित गैर स्थैतिक डेटा सदस्य, कोई आधार वर्ग नहीं, और कोई वर्चुअल फ़ंक्शन नहीं।

§8.5.1/2:

जब एक समग्र, 8.5.4 में निर्दिष्ट के रूप में एक प्रारंभकर्ता सूची से आरंभ नहीं हो जाता, प्रारंभकर्ता सूची के तत्वों के सदस्यों के लिए initializers रूप में लिया जाता सबस्क्राइब या सदस्य ऑर्डर बढ़ने में कुल। प्रत्येक सदस्य को प्रारंभकर्ता-खंड से प्रतिलिपि बनाई गई है। और नरक;

(जोर मेरा।)

साथ ही, संकलक परोक्ष एक चाल निर्माता उत्पन्न नहीं करता है, तो एक उपयोगकर्ता के घोषित प्रतिलिपि निर्माता मौजूद है (§12.8/9); क्योंकि आपके पास उपयोगकर्ता द्वारा घोषित प्रतिलिपि निर्माता है जिसे हटाए गए के रूप में परिभाषित किया गया है, A में न तो एक प्रति और न ही एक चालक कन्स्ट्रक्टर है। स्पष्ट रूप से एक कदम निर्माता जोड़ने काम करता है:

struct A 
{ 
    A(int) { } 
    A(A const&) = delete; 
    A& operator = (A const&) = delete; 
    A(A&&) = default; 
    ~A() = default; 
}; 

struct B 
{ 
    B() : a{{0}, {1}} { } 
    A a[2]; 
}; 

int main() 
{ 
    B b; 
} 

Online demo

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

+0

वह उत्तर नहीं जिसकी मैं उम्मीद कर रहा था, लेकिन विस्तृत स्पष्टीकरण के लिए धन्यवाद। – mirk

4

के भीतर एक समग्र (8.5.1) का सूची-प्रारंभ (8.5.4p1), कुल के तत्वों पर प्रदर्शन प्रारंभ के रूप में, कॉपी-प्रारंभ (8.5.1p2) है आरंभीकरण है, भले ही डायरेक्ट-सूची-प्रारंभ:

जब एक समग्र 8.5.4 में विशिष्ट एड के रूप में एक प्रारंभकर्ता सूची से आरंभ नहीं हो जाता,, प्रारंभकर्ता सूची के तत्वों initializers के रूप में कुल के सदस्यों के लिए, बढ़ती में लिया जाता है सबस्क्रिप्ट या सदस्य आदेश।प्रत्येक सदस्य को प्रारंभकर्ता-खंड से प्रतिलिपि बनाई गई है।

हालांकि, प्रारंभिक रूप से शुरू होने के रूप में प्रतिलिपि प्रारंभिक रूप का मतलब यह नहीं है कि एक प्रति होती है। copy-list-initialization of non-copyable types के अनुसार, प्रति-सूची-प्रारंभिकता स्पष्ट रचनाकारों की अनुमति नहीं है, अपवाद के साथ डायरेक्ट-लिस्ट-प्रारंभिकरण के समान होना चाहिए।

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