C ++ 20 में नामित इनिशियलाइज़र


25

मुझे c ++ 20 फीचर में से एक के बारे में एक प्रश्न मिला है, नामित इनिशियलाइज़र (इस फ़ीचर के बारे में अधिक जानकारी यहाँ )

#include <iostream>

constexpr unsigned DEFAULT_SALARY {10000};

struct Person
{
    std::string name{};
    std::string surname{};
    unsigned age{};
};

struct Employee : Person
{
    unsigned salary{DEFAULT_SALARY};
};

int main()
{
    std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed
    std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed

    Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok
    Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ?

    // For e2 compiler prints a warning "missing initializer for member 'Employee::<anonymous>' [-Wmissing-field-initializers]"
    Employee e2 {.salary{55000}}; 
}

इस कोड को 9.2.0 और -Wall -Wextra -std=gnu++2aझंडे के साथ संकलित किया गया था ।

जैसा कि आप ऊपर देख सकते हैं, दोनों संरचनाएं, Personऔर Employeeसमुच्चय हैं , लेकिन Employeeनिर्दिष्ट आरंभकों का उपयोग करते हुए कुल एकत्रीकरण संभव नहीं है।

कोई मुझे समझा सकता है क्यों?


मुझे नहीं पता कि यह आपकी समस्या को हल करता है, लेकिन आप यहाँ सार्वजनिक नहीं हो सकते हैं ...struct Employee : public Person
skratchi.at


@GSerg ठीक है, ... मैं उस पर एक विचार बर्बाद नहीं किया है, क्योंकि मैं उपयोग publicया privateहर बार ... धन्यवाद वैसे भी
skratchi.at

आपकी सटीक त्रुटि क्या है?
skratchi.at

2
@ skratchi.at structडिफ़ॉल्ट रूप से सार्वजनिक रूप से विरासत में
मिली

जवाबों:


15

C ++ 20 मानक के अनुसार (9.3.1 समुच्चय। पृष्ठ # 3)

(३.१) - यदि इनिशियलाइज़र सूची निर्दिष्ट-इनिशियलाइज़र-लिस्ट है, तो एग्रीगेट क्लास के प्रकार का होगा, प्रत्येक डिज़ाइनर में पहचानकर्ता क्लास के एक डायरेक्ट नॉन-स्टैटिक डेटा मेंबर , और एग्रीगेट के स्पष्ट रूप से इनिशियलाइज्ड एलिमेंट्स को नाम देगा। वे तत्व हैं जो हैं, या हैं, वे सदस्य हैं।

इसलिए आप आधार वर्गों के डेटा सदस्यों को आरंभीकृत करने के लिए नामित प्रारंभिक सूची का उपयोग नहीं कर सकते हैं।

इसके बजाय सामान्य सूची आरंभीकरण की तरह उपयोग करें

Employee e1{ "John", "Wick", 40, 50000 };

या

Employee e1{ { "John", "Wick", 40 }, 50000 };

या जैसा कि @ Jarod42 ने टिप्पणी में बताया है कि आप लिख सकते हैं

Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };

इस मामले में प्रत्यक्ष आधार वर्ग को एक निर्दिष्ट प्रारंभिक सूची द्वारा आरंभीकृत किया जाता है जबकि पूरी तरह से वर्ग एम्प्लोय को गैर-नामित प्रारंभिक सूची द्वारा आरंभ किया जाता है।


3
या एक मिश्रण Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };:।
Jarod42

@ Jarod42 हाँ, यह संकलित करता है।
मास्को से

5

आपके पास अलग-अलग ठिकानों से एक ही नाम के कई क्षेत्र हो सकते हैं,

इसलिए तार्किक रूप से, आपको वांछित आधार का नाम प्रदान करना चाहिए, लेकिन ऐसा लगता है कि ऐसा करने का कोई तरीका नहीं है।

// Invalid too:
Employee e1{.Person.name{"John"}, .Person.surname{"Wick"}, .Person.age{40}, .salary{50000}};
Employee e2{.Person{.name{"John"}, .surname{"Wick"}, .age{40}}, .salary{50000}};

इसके अलावा C ++ द्वारा निर्दिष्ट इनिशियलाइज़ेशन C की तुलना में अधिक विवश है:

नोट: आउट-ऑफ-ऑर्डर नामित इनिशियलाइज़ेशन, नेस्टेड इनिशियलाइज़ेशन, नेक्ड इनिशियलाइज़र्स और रेगुलर इनिशियलाइज़र्स का मिश्रण, और एरे के निर्दिष्ट इनिशियलाइज़ेशन सभी C प्रोग्रामिंग लैंग्वेज में समर्थित हैं, लेकिन C ++ में इसकी अनुमति नहीं है।

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