सी ++ संरचना प्रारंभिक


279

क्या यह संभव है कि सी ++ में स्ट्रक्चर्स को इनिशियलाइज़ किया जा सके

struct address {
    int street_no;
    char *street_name;
    char *city;
    char *prov;
    char *postal_code;
};
address temp_address =
    { .city = "Hamilton", .prov = "Ontario" };

यहां और यहां दिए गए लिंक में उल्लेख किया गया है कि इस शैली का उपयोग केवल सी में करना संभव है। यदि ऐसा है तो सी ++ में यह क्यों संभव नहीं है? क्या कोई अंतर्निहित तकनीकी कारण है कि इसे C ++ में लागू क्यों नहीं किया गया है, या क्या इस शैली का उपयोग करने के लिए यह बुरा अभ्यास है। मुझे इनिशियलाइज़ करने के इस तरीके का उपयोग करना पसंद है क्योंकि मेरी संरचना बड़ी है और यह शैली मुझे इस बात की स्पष्ट पठनीयता देती है कि किस सदस्य को क्या मूल्य सौंपा जाए।

कृपया मेरे साथ साझा करें यदि अन्य तरीके हैं जिनके माध्यम से हम उसी पठनीयता को प्राप्त कर सकते हैं।

मैंने इस प्रश्न को पोस्ट करने से पहले निम्नलिखित लिंक का उल्लेख किया है

  1. AIX के लिए C / C ++
  2. चर के साथ सी संरचना प्रारंभिक
  3. C ++ में टैग्स के साथ स्टेटिक स्ट्रक्चर इनिशियलाइज़ेशन
  4. C ++ 11 उचित संरचना प्रारंभ

20
दुनिया का व्यक्तिगत दृष्टिकोण: आपको C ++ में ऑब्जेक्ट इनिशियलाइज़ेशन की इस शैली की आवश्यकता नहीं है क्योंकि आपको इसके बजाय एक कंस्ट्रक्टर का उपयोग करना चाहिए।
फिलिप केंडल

7
हां, मैंने इसके बारे में सोचा, लेकिन मेरे पास बड़ी संरचना की एक सरणी है। इस तरह इस्तेमाल करना मेरे लिए आसान और पठनीय होगा। क्या आपके पास कंस्ट्रक्टर का उपयोग करने की शुरुआत करने की कोई शैली / अच्छा अभ्यास है जो बेहतर पठनीयता देता है।
दिनेश पीआर

2
क्या आपने बूस्टर के साथ संयोजन में बूस्ट पैरामीटर लाइब्रेरी पर विचार किया है? boost.org/doc/libs/1_50_0/libs/parameter/doc/html/index.html
टोनी

18
प्रोग्रामिंग से संबंधित नहीं: यह पता केवल अमेरिका में ठीक काम करता है। फ्रांस में, हमारे पास "प्रांत" नहीं है, दुनिया के अन्य हिस्सों में, कोई पोस्टल कोड नहीं है, एक दोस्त की दादी-मां इतने छोटे से गाँव में रहती हैं कि उनका पता "Ms X", पोस्टल-कोड है छोटा-गाँव-नाम "(हाँ, कोई सड़क नहीं)। तो ध्यान से विचार करें कि आपके द्वारा इस पर लागू होने वाले बाज़ार का एक वैध पता क्या है?)
मैथ्यू एम।

5
@MatthieuM। अमेरिका में कोई प्रांत नहीं हैं (यह एक कनाडाई प्रारूप हो सकता है?), लेकिन राज्य, क्षेत्र और यहां तक ​​कि छोटे गांव भी हैं जो सड़कों का नाम नहीं लेते हैं। तो पते की पुष्टि का मुद्दा यहां भी लागू होता है।
टिम

जवाबों:


166

यदि आप यह स्पष्ट करना चाहते हैं कि प्रत्येक प्रारंभिक मूल्य क्या है, तो इसे प्रत्येक पर एक टिप्पणी के साथ, कई लाइनों पर विभाजित करें:

address temp_addres = {
  0,  // street_no
  nullptr,  // street_name
  "Hamilton",  // city
  "Ontario",  // prov
  nullptr,  // postal_code
};

7
मैं व्यक्तिगत रूप से इस शैली को पसंद करता हूं और इसकी सिफारिश करता हूं
दिनेश पीआर

30
ऐसा करने में क्या अंतर है, और वास्तव में और अधिक फ़ील्ड को एक्सेस करने के लिए डॉट नोटेशन का उपयोग करके, इसकी तरह आप इसकी किसी भी जगह को नहीं बचा रहे हैं यदि यह चिंता है। मुझे वास्तव में C ++ प्रोग्रामर नहीं मिलते हैं जब यह सुसंगत होने और बनाए रखने योग्य कोड लिखने की बात आती है, तो वे हमेशा अपने कोड को अलग करने के लिए कुछ अलग करना चाहते हैं, कोड का मतलब समस्या को प्रतिबिंबित करने के लिए होता है जिसे हल नहीं किया जाना चाहिए। अपने दम पर एक मुहावरा, विश्वसनीयता और रखरखाव में आसानी के लिए लक्ष्य।

5
@ user1043000 अच्छी तरह से, एक के लिए, इस मामले में जिस क्रम में आप अपने सदस्यों को डालते हैं वह अत्यधिक महत्व का है। यदि आप अपनी संरचना के बीच में एक फ़ील्ड जोड़ते हैं, तो आपको इस कोड पर वापस जाना होगा और उस सटीक स्थान की तलाश करनी होगी जिसमें अपनी नई इनिशियलाइज़ेशन सम्मिलित करना है, जो कठिन और उबाऊ है। डॉट नोटेशन के साथ, आप बस आदेश के साथ परेशान किए बिना सूची के अंत में अपना नया इनिशियलाइज़ेशन डाल सकते हैं। और यदि आप char*संरचना में ऊपर या नीचे अन्य सदस्यों में से एक के रूप में एक ही प्रकार (जैसे ) को जोड़ने के लिए होते हैं, तो डॉट नोटेशन अधिक सुरक्षित है , क्योंकि उन्हें स्वैप करने का कोई जोखिम नहीं है।
गुई

6
orip की टिप्पणी। यदि डेटा संरचना की परिभाषा बदल जाती है, और कोई भी आरंभीकरण को देखने के लिए नहीं सोचता है, या उन सभी को नहीं ढूंढ सकता है, या उन्हें संपादित करने में गलती करता है, तो चीजें अलग हो जाएंगी।
एडवर्ड फल्क

3
अधिकांश (यदि सभी नहीं) तो POSIX संरचना में एक परिभाषित क्रम नहीं है, केवल परिभाषित सदस्य हैं। (struct timeval){ .seconds = 0, .microseconds = 100 }हमेशा सौ माइक्रोसेकंड होगा, लेकिन timeval { 0, 100 }एक सौ सेकंड हो सकता है । आप ऐसा कुछ नहीं ढूंढना चाहते हैं जो कठिन हो।
yyny

99

मेरे प्रश्न के बाद कोई संतोषजनक परिणाम नहीं मिला (क्योंकि C ++ संरचनाओं के लिए टैग-आधारित init को लागू नहीं करता है), मैंने यहां पाई गई चाल ली: क्या C ++ के सदस्य डिफ़ॉल्ट रूप से 0 से आरम्भ हुए हैं?

आपके लिए यह करने की राशि होगी:

address temp_address = {}; // will zero all fields in C++
temp_address.city = "Hamilton";
temp_address.prov = "Ontario";

यह निश्चित रूप से वही है जो आप मूल रूप से चाहते थे (उन सभी क्षेत्रों को शून्य करें जिन्हें आप शुरू करना चाहते हैं)।


10
यह सांख्यिकीय रूप से inintialized ऑब्जेक्ट्स के लिए काम नहीं करता है
user877329

5
static address temp_address = {};काम करेगा। बाद में इसे भरना रनटाइम तक है, हाँ। आप इसे एक स्थैतिक फ़ंक्शन प्रदान करके बाईपास कर सकते हैं जो आपके लिए init करता है static address temp_address = init_my_temp_address();:।
गुई 13

C ++ 11 में, init_my_temp_addressएक static address temp_address = [] () { /* initialization code */ }();
लंबोदा

3
बुरा विचार, यह RAII सिद्धांत का उल्लंघन करता है।
hxpax

2
वास्तव में बुरा विचार: एक सदस्य को अपने में जोड़ें addressऔर आप उन सभी स्थानों के बारे में कभी नहीं जान पाएंगे जो addressअब बनाते हैं और अब अपने नए सदस्य को प्रारंभ नहीं करते हैं।
मिस्ट्री_डॉक्टर

25

जैसा कि दूसरों ने उल्लेख किया है कि यह आरंभिक नामित है।

यह सुविधा C ++ 20 का हिस्सा है


17

क्षेत्र के पहचानकर्ता वास्तव में सी इनिशियल सिंटैक्स हैं। C ++ में केवल फ़ील्ड नामों के बिना सही क्रम में मान दें। दुर्भाग्य से इसका मतलब है कि आपको उन सभी को देने की आवश्यकता है (वास्तव में आप शून्य-मूल्यवान क्षेत्रों को पीछे छोड़ सकते हैं और परिणाम समान होगा):

address temp_address = { 0, 0, "Hamilton", "Ontario", 0 }; 

1
हाँ, आप हमेशा संरेखित संरचना आरंभीकरण का उपयोग कर सकते हैं।
टेक्ससब्रूस

3
हां, वर्तमान में मैं केवल इस पद्धति का उपयोग कर रहा हूं (संरेखित संरचना प्रारंभ)। लेकिन मुझे लगता है कि पठनीयता अच्छी नहीं है। चूंकि मेरा स्ट्रक्चर बड़ा है, इसलिए इनिशियलाइज़र के पास बहुत सारे डेटा हैं और मेरे लिए यह ट्रैक करना मुश्किल है कि कौन सा मूल्य किस सदस्य को सौंपा गया है।
दिनेश PR

7
@ DineshP.R। फिर एक रचनाकार लिखो!
मिस्टर लिस्टर

2
@ मिस्टर (या कोई भी) शायद मैं इस समय मूर्खता के एक बादल में फंस गया हूं, लेकिन इस बात की परवाह करना कि एक कंस्ट्रक्टर कितना बेहतर होगा? मुझे लगता है कि प्रारंभिक सूची में ऑर्डर-निर्भर अनाम मानों का एक गुच्छा प्रदान करने या एक निर्माता को आदेश-निर्भर अनाम मानों का एक गुच्छा प्रदान करने के बीच बहुत अंतर है ...?
yano

1
@yano ईमानदार होना, मुझे वास्तव में याद नहीं है कि मैंने क्यों सोचा कि एक निर्माता समस्या का जवाब होगा। अगर मुझे याद है, तो मैं तुम्हारे पास वापस आऊंगा।
श्री लिस्टर

13

इस सुविधा को नामित इनिशियलाइज़र कहा जाता है । यह C99 मानक के अतिरिक्त है। हालाँकि, इस सुविधा को C ++ 11 से छोड़ दिया गया था। द सी ++ प्रोग्रामिंग लैंग्वेज के अनुसार, 4 वां संस्करण, धारा 44.3.3.2 (सी फीचर्स एडॉप्टेड नॉट सी + +):

C99 में कुछ जोड़ (C89 की तुलना में) जानबूझकर C ++ में नहीं अपनाए गए:

[१] वैरिएबल-लेंथ एरे (वीएलए); वेक्टर या डायनामिक ऐरे के किसी रूप का उपयोग करें

[२] नामित आरंभीकरण; निर्माणकर्ताओं का उपयोग करें

C99 व्याकरण में निर्दिष्ट आरंभीकरण हैं [ISO / IEC 9899 देखें: 2011, N1570 समिति ड्राफ्ट - 12 अप्रैल, 2011]

6.7.9 इनिशियलाइज़ेशन

initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
initializer-list:
    designation_opt initializer
    initializer-list , designationopt initializer
designation:
    designator-list =
designator-list:
    designator
    designator-list designator
designator:
    [ constant-expression ]
    . identifier

दूसरी ओर, C ++ 11 में निर्दिष्ट इनिशियलाइज़र नहीं हैं [देखें ISO / IEC 14882: 2011, N3690 समिति ड्राफ्ट - 15 मई, 2013]

8.5 प्रारंभिक

initializer:
    brace-or-equal-initializer
    ( expression-list )
brace-or-equal-initializer:
    = initializer-clause
    braced-init-list
initializer-clause:
    assignment-expression
    braced-init-list
initializer-list:
    initializer-clause ...opt
    initializer-list , initializer-clause ...opt
braced-init-list:
    { initializer-list ,opt }
    { }

उसी प्रभाव को प्राप्त करने के लिए, निर्माणकर्ताओं या आरंभीकरण सूचियों का उपयोग करें:


9

आप बस ctor के माध्यम से इनिशियलाइज़ कर सकते हैं:

struct address {
  address() : city("Hamilton"), prov("Ontario") {}
  int street_no;
  char *street_name;
  char *city;
  char *prov;
  char *postal_code;
};

9
यह केवल तभी होता है जब आप परिभाषा को नियंत्रित करते हैं struct address। इसके अलावा, POD प्रकारों में जानबूझकर कोई कंस्ट्रक्टर और विध्वंसक नहीं होता है।
user4815162342

7

आप Gui13 के समाधान को एकल इनिशियलाइज़ेशन स्टेटमेंट में भी पैक कर सकते हैं:

struct address {
                 int street_no;
                 char *street_name;
                 char *city;
                 char *prov;
                 char *postal_code;
               };


address ta = (ta = address(), ta.city = "Hamilton", ta.prov = "Ontario", ta);

अस्वीकरण: मैं इस शैली की सिफारिश नहीं करता


यह अभी भी खतरनाक है क्योंकि यह आपको एक सदस्य को जोड़ने की अनुमति देता है addressऔर कोड अभी भी एक लाख स्थानों के साथ संकलन करेगा जो केवल मूल पांच सदस्यों को शुरू करेगा। संरचना आरंभीकरण का सबसे अच्छा हिस्सा यह है कि आपके पास सभी सदस्य हो सकते हैं constऔर यह आपको उन सभी को शुरू करने के लिए मजबूर करेगा
मिस्ट्री_डॉक्टर

7

मुझे पता है कि यह सवाल काफी पुराना है, लेकिन मुझे कॉन्स्ट्रेक्स और करीने का उपयोग करने का एक और तरीका मिला:

struct mp_struct_t {
    public:
        constexpr mp_struct_t(int member1) : mp_struct_t(member1, 0, 0) {}
        constexpr mp_struct_t(int member1, int member2, int member3) : member1(member1), member2(member2), member3(member3) {}
        constexpr mp_struct_t another_member(int member) { return {member1, member,     member2}; }
        constexpr mp_struct_t yet_another_one(int member) { return {member1, member2, member}; }

    int member1, member2, member3;
};

static mp_struct_t a_struct = mp_struct_t{1}
                           .another_member(2)
                           .yet_another_one(3);

यह विधि वैश्विक स्थिर वैरिएबल और यहां तक ​​कि बाधा वाले लोगों के लिए भी काम करती है। एकमात्र नुकसान खराब रखरखाव है: इस विधि का उपयोग करके हर बार किसी अन्य सदस्य को प्रारंभिक बनाया जा सकता है, सभी सदस्य आरंभीकरण के तरीकों को बदलना होगा।


1
यह बिल्डर पैटर्न है । सदस्य विधियां हर बार एक नई संरचना बनाने के बजाय संशोधित की जाने वाली संपत्ति का संदर्भ लौटा सकती हैं
phuclv

6

मुझे यहाँ कुछ याद आ रहा है, क्यों नहीं:

#include <cstdio>    
struct Group {
    int x;
    int y;
    const char* s;
};

int main() 
{  
  Group group {
    .x = 1, 
    .y = 2, 
    .s = "Hello it works"
  };
  printf("%d, %d, %s", group.x, group.y, group.s);
}

मैंने ऊपर के कार्यक्रम को एक मिनगीडब्ल्यू सी ++ कंपाइलर और एक अरुडिनो एवीआर सी ++ कंपाइलर के साथ संकलित किया, और दोनों अपेक्षित रूप से चले। #Include <cstdio>
run_the_race

4
@run_the_race, यह इस बारे में है कि c ++ मानक क्या कहता है कि एक संकलक का व्यवहार क्या हो सकता है। हालाँकि, यह सुविधा c ++ 20 में आ रही है।
जॉन

यह केवल तभी काम करता है यदि संरचना POD है। तो अगर आप इसमें कंस्ट्रक्टर जोड़ते हैं तो यह संकलन बंद हो जाएगा।
oromoiluig

5

यह C ++ में लागू नहीं है। (भी, char*तार। मुझे आशा है कि नहीं)।

आमतौर पर अगर आपके पास इतने सारे पैरामीटर हैं तो यह काफी गंभीर कोड गंध है। लेकिन इसके बजाय, केवल संरचना को मूल्य-प्रारंभिक क्यों नहीं किया जाए और फिर प्रत्येक सदस्य को असाइन करें?


6
"(भी, char*स्ट्रिंग्स? मुझे आशा है कि नहीं)।" - खैर, यह एक C उदाहरण है।
एड एस।

खिचड़ी भाषा का उपयोग हम सी + + में करते हैं? वर्तमान में मैं इसका उपयोग कर रहा हूं और यह काम कर रहा है (हो सकता है कि मैं कुछ गलत कर रहा हूं)। मेरी धारणा यह है कि कंपाइलर "हैमिल्टन" और "ओंटारियो" के लगातार तार बनाएंगे और उनके पते को सदस्यों को सौंपेंगे। क्या इसके बजाय कास्ट चार * का उपयोग करना सही होगा?
दिनेश PR

8
आप उपयोग कर सकते हैं char*लेकिन const char*बहुत अधिक प्रकार-सुरक्षित है और हर कोई सिर्फ std::stringइसलिए उपयोग करता है क्योंकि यह बहुत अधिक विश्वसनीय है।
पिल्ला

ठीक। जब मैंने "जैसा कि नीचे उल्लेख किया गया है" पढ़ा, मैंने मान लिया कि यह कहीं से कॉपी किया गया उदाहरण है।
एड एस।

2

मैंने इसे वैश्विक चर के लिए ऐसा करने का तरीका पाया, जिसमें मूल संरचना की परिभाषा को संशोधित करने की आवश्यकता नहीं है:

struct address {
             int street_no;
             char *street_name;
             char *city;
             char *prov;
             char *postal_code;
           };

फिर मूल संरचना प्रकार से विरासत में मिले एक नए प्रकार के चर की घोषणा करें और खेतों को प्रारंभिककरण के लिए निर्माणकर्ता का उपयोग करें:

struct temp_address : address { temp_address() { 
    city = "Hamilton"; 
    prov = "Ontario"; 
} } temp_address;

हालांकि सी शैली के रूप में बहुत सुंदर नहीं ...

स्थानीय वैरिएबल के लिए इसे कंस्ट्रक्टर की शुरुआत में अतिरिक्त मेमसेट (यह, 0, साइज़ोफ़ (* यह)) की आवश्यकता होती है, इसलिए यह स्पष्ट रूप से खराब नहीं होता है और @ gui13 का उत्तर अधिक उपयुक्त है।

(ध्यान दें कि 'temp_address' एक प्रकार का 'temp_address' है, हालांकि यह नया प्रकार 'पता' से प्राप्त होता है और इसका उपयोग हर उस स्थान पर किया जा सकता है जहाँ 'पता' अपेक्षित है, इसलिए यह ठीक है।)


1

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

मैंने संरचना में एक रचनाकार फ़ंक्शन के साथ जाना समाप्त कर दिया, जो मुझे लगता है कि आपके प्रश्न के कुछ उत्तरों में भी सुझाया गया था।

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

typedef struct testdatum_s {
    public:
    std::string argument1;
    std::string argument2;
    std::string argument3;
    std::string argument4;
    int count;

    testdatum_s (
        std::string argument1,
        std::string argument2,
        std::string argument3,
        std::string argument4,
        int count)
    {
        this->rotation = argument1;
        this->tstamp = argument2;
        this->auth = argument3;
        this->answer = argument4;
        this->count = count;
    }

} testdatum;

इस तरह के विभिन्न तर्कों के साथ परीक्षण किए जा रहे फ़ंक्शन को कॉल करने के लिए मैंने अपने परीक्षण फ़ंक्शन का उपयोग किया:

std::vector<testdatum> testdata;

testdata.push_back(testdatum("val11", "val12", "val13", "val14", 5));
testdata.push_back(testdatum("val21", "val22", "val23", "val24", 1));
testdata.push_back(testdatum("val31", "val32", "val33", "val34", 7));

for (std::vector<testdatum>::iterator i = testdata.begin(); i != testdata.end(); ++i) {
    function_in_test(i->argument1, i->argument2, i->argument3, i->argument4m i->count);
}

1

यह संभव है, लेकिन केवल अगर आप जिस संरचना को शुरू कर रहे हैं वह एक POD (सादा पुराना डेटा) संरचना है। इसमें कोई भी विधि, निर्माता या डिफ़ॉल्ट मान शामिल नहीं हो सकते।


1

C ++ में C- स्टाइल इनिशियलाइज़र को कंस्ट्रक्टरों द्वारा प्रतिस्थापित किया गया था जो कि संकलन समय द्वारा सुनिश्चित कर सकते हैं कि केवल मान्य इनिशियलाइज़ेशन किए गए हैं (यानी इनिशियलाइज़ेशन के बाद ऑब्जेक्ट मेंबर्स सुसंगत हैं)।

यह एक अच्छा अभ्यास है, लेकिन कभी-कभी आपके उदाहरण में पूर्व-टीकाकरण आसान होता है। ओओपी इसे अमूर्त कक्षाओं या रचनात्मक डिजाइन पैटर्न द्वारा हल करता है ।

मेरी राय में, इस सुरक्षित तरीके का उपयोग करना सादगी को मारता है और कभी-कभी सुरक्षा व्यापार बंद बहुत महंगा हो सकता है, क्योंकि सरल कोड को बनाए रखने के लिए परिष्कृत डिजाइन की आवश्यकता नहीं होती है।

एक वैकल्पिक समाधान के रूप में, मैं सी-स्टाइल की तरह दिखने के लिए इनिशियलाइज़ेशन को आसान बनाने के लिए मेमने का उपयोग करते हुए मैक्रोज़ को परिभाषित करने का सुझाव देता हूं:

struct address {
  int street_no;
  const char *street_name;
  const char *city;
  const char *prov;
  const char *postal_code;
};
#define ADDRESS_OPEN [] { address _={};
#define ADDRESS_CLOSE ; return _; }()
#define ADDRESS(x) ADDRESS_OPEN x ADDRESS_CLOSE

ADDRESS मैक्रो का विस्तार होता है

[] { address _={}; /* definition... */ ; return _; }()

जो लैम्ब्डा बनाता है और कॉल करता है। मैक्रो मापदंडों को भी अलग किया जाता है, इसलिए आपको इनिशियलाइज़र को कोष्ठक में रखने और कॉल करने की आवश्यकता होती है

address temp_address = ADDRESS(( _.city = "Hamilton", _.prov = "Ontario" ));

आप सामान्यीकृत मैक्रो इनिशियलाइज़र भी लिख सकते हैं

#define INIT_OPEN(type) [] { type _={};
#define INIT_CLOSE ; return _; }()
#define INIT(type,x) INIT_OPEN(type) x INIT_CLOSE

लेकिन फिर कॉल थोड़ा कम सुंदर है

address temp_address = INIT(address,( _.city = "Hamilton", _.prov = "Ontario" ));

हालाँकि आप सामान्य INIT मैक्रो का उपयोग करके ADDRESS मैक्रो को आसानी से परिभाषित कर सकते हैं

#define ADDRESS(x) INIT(address,x)

1

GNUC ++ में (2.5 के बाद से अप्रचलित प्रतीत होता है, एक लंबे समय से पहले :) यहां दिए गए उत्तर देखें: लेबल का उपयोग करके सी संरचना आरंभीकरण। यह काम करता है, लेकिन कैसे? ), इस तरह की संरचना को शुरू करना संभव है:

struct inventory_item {
    int bananas;
    int apples;
    int pineapples;
};

inventory_item first_item = {
    bananas: 2,
    apples: 49,
    pineapples: 4
};

0

इस बहुत साफ जवाब से प्रेरित: ( https://stackoverflow.com/a/49572324/4808079 )

आप लांबा क्लोजर कर सकते हैं:

// Nobody wants to remember the order of these things
struct SomeBigStruct {
  int min = 1;
  int mean = 3 ;
  int mode = 5;
  int max = 10;
  string name;
  string nickname;
  ... // the list goes on
}

class SomeClass {
  static const inline SomeBigStruct voiceAmps = []{
    ModulationTarget $ {};
    $.min = 0;  
    $.nickname = "Bobby";
    $.bloodtype = "O-";
    return $;
  }();
}

या, यदि आप बहुत फैंसी होना चाहते हैं

#define DesignatedInit(T, ...)\
  []{ T ${}; __VA_ARGS__; return $; }()

class SomeClass {
  static const inline SomeBigStruct voiceAmps = DesignatedInit(
    ModulationTarget,
    $.min = 0,
    $.nickname = "Bobby",
    $.bloodtype = "O-",
  );
}

इसमें कुछ कमियां शामिल हैं, जिनमें ज्यादातर असंगठित सदस्यों के साथ हैं। लिंक किए गए उत्तर टिप्पणियों से क्या कहते हैं, यह कुशलता से संकलित करता है, हालांकि मैंने इसका परीक्षण नहीं किया है।

कुल मिलाकर, मुझे लगता है कि यह एक साफ दृष्टिकोण है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.