C ++ ज़ीरो इनिशियलाइज़ेशन - इस प्रोग्राम में `b` को अनइंस्टाल्यूट क्यों किया जाता है, लेकिन` a` को इनिशियलाइज़ किया जाता है?


135

इस स्टैक ओवरफ्लो प्रश्न के लिए स्वीकृत (और केवल) उत्तर के अनुसार ,

कंस्ट्रक्टर के साथ परिभाषित करना

MyTest() = default;

इसके बजाय ऑब्जेक्ट को शून्य-आरंभ करेगा।

फिर निम्न क्यों करता है,

#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b;
};

bar::bar() = default;

int main() {
    foo a{};
    bar b{};
    std::cout << a.a << ' ' << b.b;
}

इस उत्पादन का उत्पादन:

0 32766

परिभाषित दोनों कंस्ट्रक्टर डिफ़ॉल्ट हैं? सही? और POD प्रकारों के लिए, डिफ़ॉल्ट आरंभीकरण शून्य-आरंभीकरण है।

और इस प्रश्न के स्वीकृत उत्तर के अनुसार ,

  1. यदि एक पीओडी सदस्य को कंस्ट्रक्टर में आरंभीकृत नहीं किया गया है और न ही सी ++ 11 इन-क्लास आरंभीकरण के माध्यम से, यह डिफ़ॉल्ट-आरंभीकृत है।

  2. स्टैक या हीप की परवाह किए बिना उत्तर समान है।

  3. C ++ 98 (और बाद में नहीं) में, नया int () शून्य आरंभीकरण प्रदर्शन के रूप में निर्दिष्ट किया गया था।

डिफॉल्ट कंस्ट्रक्टर्स और डिफॉल्ट इनिशियलाइज़ेशन के आसपास मेरे (यद्यपि छोटे ) सिर को लपेटने की कोशिश करने के बावजूद , मैं एक स्पष्टीकरण के साथ नहीं आ सका।


3
दिलचस्प बात यह है कि मुझे b: main.cpp: 18: 34: चेतावनी: 'b.bar::b' का भी उपयोग किया जाता है, जो इस समारोह में अनइंस्टाल्यूट किया जाता है [-Wuninitialized] coliru.stacked-croed.com/a/d1b08a4d6fb4ca7e
tkausl 15:24 बजे

8
barनिर्माणकर्ता उपयोगकर्ता प्रदान किया गया है, जबकि fooनिर्माणकर्ता डिफ़ॉल्ट रूप से एक है।
Jarod42

2
@PeteBecker, मैं समझता हूँ कि। मैं किसी तरह अपनी रैम को थोड़ा हिला सकता हूं ताकि अगर वहां शून्य हो, तो यह अब कुछ और होना चाहिए। ;) पी एस मैं एक दर्जन बार कार्यक्रम चलाया। यह कोई बड़ा कार्यक्रम नहीं है। आप इसे चला सकते हैं और अपने सिस्टम पर इसका परीक्षण कर सकते हैं। aशून्य है। bनहीं है। लगता aहै शुरू में।
डक डोजर्स

2
@JoeyMallone के बारे में "यह कैसे उपयोगकर्ता-प्रदान किया जाता है": इस बात की कोई गारंटी नहीं है कि इसमें जो परिभाषा bar::bar()दिखाई दे रही है main()- वह एक अलग संकलन इकाई में परिभाषित हो सकती है और कुछ बहुत ही गैर-तुच्छ कार्य कर सकती है जबकि main()केवल घोषणा दिखाई दे रही है। मुझे लगता है कि आप सहमत होंगे कि यह व्यवहार इस बात पर निर्भर नहीं होना चाहिए कि आप bar::bar()एक अलग संकलन इकाई में परिभाषा रखते हैं या नहीं (भले ही पूरी स्थिति एकरूप हो)।
मैक्स लैंगहॉफ

2
@balki या int a = 0;क्या आप वास्तव में स्पष्ट होना चाहते हैं।
नाथनऑलिवर

जवाबों:


109

यहाँ मुद्दा बहुत सूक्ष्म है। आप ऐसा सोचेंगे

bar::bar() = default;

आपको एक कंपाइलर जनरेट किया गया डिफॉल्ट कंस्ट्रक्टर देगा, और यह करता है, लेकिन अब इसे उपयोगकर्ता द्वारा प्रदान किया गया माना जाता है। [dcl.fct.def.default] / 5 राज्य:

स्पष्ट रूप से डिफॉल्ट किए गए फ़ंक्शंस और अंतर्निहित रूप से घोषित फ़ंक्शंस को सामूहिक रूप से डिफॉल्ट फ़ंक्शंस कहा जाता है, और कार्यान्वयन उनके लिए निहित परिभाषाएँ प्रदान करेगा ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy .assign) ]), जिसका अर्थ हो सकता है उन्हें हटाए जाने के रूप में परिभाषित करना। एक फ़ंक्शन उपयोगकर्ता-प्रदान किया गया है यदि यह उपयोगकर्ता-घोषित है और इसकी पहली घोषणा पर स्पष्ट रूप से डिफ़ॉल्ट या हटा नहीं है।एक उपयोगकर्ता द्वारा प्रदान किया गया स्पष्ट रूप से डिफ़ॉल्ट रूप से फ़ंक्शन (यानी, इसकी पहली घोषणा के बाद स्पष्ट रूप से डिफ़ॉल्ट) को उस बिंदु पर परिभाषित किया गया है जहां यह स्पष्ट रूप से डिफ़ॉल्ट रूप से डिफ़ॉल्ट है; यदि ऐसा फ़ंक्शन अंतर्निहित रूप से हटाए जाने के रूप में परिभाषित किया गया है, तो प्रोग्राम बीमार है। [नोट: किसी फ़ंक्शन को पहले घोषणा के बाद डिफ़ॉल्ट के रूप में घोषित करना एक कुशल कोड बेस के लिए एक स्थिर बाइनरी इंटरफ़ेस को सक्षम करते हुए कुशल निष्पादन और संक्षिप्त परिभाषा प्रदान कर सकता है। - अंतिम नोट]

जोर मेरा

इसलिए हम देख सकते हैं कि bar()जब आपने पहली बार घोषणा की थी तब आप डिफ़ॉल्ट नहीं थे , अब इसे उपयोगकर्ता द्वारा प्रदान किया गया माना जाता है। उसके कारण [dcl.init] / 8.2

यदि T उपयोगकर्ता-प्रदान या हटाए गए डिफ़ॉल्ट निर्माणकर्ता के बिना एक (संभवतः cv-योग्य) वर्ग प्रकार है, तो ऑब्जेक्ट को शून्य-आरंभीकृत किया गया है और डिफ़ॉल्ट-आरंभीकरण के लिए सिमेंटिक बाधाओं की जाँच की जाती है, और यदि T में एक गैर-सामान्य डिफ़ॉल्ट निर्माता है ऑब्जेक्ट डिफ़ॉल्ट-आरंभीकृत है;

अब लागू नहीं होता है और हम आरंभिक मूल्य नहीं कर रहे हैं, bबल्कि इसे [dcl.init] / 8.1 प्रति डिफ़ॉल्ट रूप से आरंभ कर रहे हैं

यदि T एक (संभवतः cv-योग्य) वर्ग प्रकार ([वर्ग]) है जिसमें या तो कोई डिफ़ॉल्ट निर्माता नहीं है ([class.default.ctor]) या एक डिफ़ॉल्ट निर्माता जो उपयोगकर्ता द्वारा प्रदान किया गया है या हटा दिया गया है, तो ऑब्जेक्ट डिफ़ॉल्ट-प्रारंभिक है ;


52
मेरा मतलब है (*_*).... अगर भाषा के बुनियादी निर्माणों का उपयोग करने के लिए, मुझे भाषा के मसौदे के ठीक प्रिंट को पढ़ने की जरूरत है, तो हेलेलुजाह! लेकिन यह शायद आप कहते हैं कि लगता है।
बतख डोजर्स

12
@ बाल्की हां, bar::bar() = defaultलाइन से बाहर करना bar::bar(){}इनलाइन करने के समान है ।
नाथनऑलिवर

15
@JoeyMallone हाँ, C ++ बहुत जटिल हो सकता है। मुझे यकीन नहीं है कि इसका कारण क्या है।
नेथनऑलिवर

3
यदि पिछली घोषणा है, तो डिफ़ॉल्ट कीवर्ड के साथ एक बाद की परिभाषा सदस्यों को शून्य नहीं करेगी। सही? यह सही है। यहां वही हो रहा है।
नाथनऑलिवर

6
आपके उद्धरण में कारण सही है: एक आउट-ऑफ-लाइन डिफ़ॉल्ट का बिंदु "एक कुशल कोड बेस के लिए एक स्थिर बाइनरी इंटरफ़ेस को सक्षम करने के दौरान कुशल निष्पादन और संक्षिप्त परिभाषा प्रदान करना है", दूसरे शब्दों में, आपको स्विच करने में सक्षम करें उपयोगकर्ता-लिखित निकाय बाद में यदि आवश्यक हो तो एबीआई को तोड़े बिना। ध्यान दें कि आउट-ऑफ-लाइन परिभाषा अंतर्निहित रूप से इनलाइन नहीं है और इसलिए केवल डिफ़ॉल्ट रूप से एक टीयू में दिखाई दे सकती है; एक अन्य टीयू को कक्षा की परिभाषा को देखकर यह जानने का कोई तरीका नहीं है कि क्या इसे स्पष्ट रूप से डिफ़ॉल्ट रूप से परिभाषित किया गया है।
तृकां

25

व्यवहार में अंतर तथ्य यह है कि, के अनुसार से आता है [dcl.fct.def.default]/5, bar::barहै उपयोगकर्ता द्वारा प्रदान की जहां foo::fooनहीं है 1 । परिणामस्वरूप, अपने सदस्यों foo::fooको मूल्य-आरंभ कर देगा (अर्थ: शून्य-आरंभ foo::a ) लेकिन bar::barअनैतिक रूप से 2 रहेंगे ।


1) [dcl.fct.def.default]/5

एक फ़ंक्शन उपयोगकर्ता-प्रदान किया गया है यदि यह उपयोगकर्ता-घोषित है और इसकी पहली घोषणा पर स्पष्ट रूप से डिफ़ॉल्ट या हटा नहीं है।

2)

से [dcl.init # 6] :

टी प्रकार की एक वस्तु को महत्व देने के लिए इसका मतलब है:

  • यदि T एक (संभवतः cv-योग्य) वर्ग प्रकार है, जिसमें कोई डिफ़ॉल्ट कंस्ट्रक्टर ([class.ctor]) या एक डिफॉल्ट कंस्ट्रक्टर जो उपयोगकर्ता द्वारा प्रदान किया गया है या हटा दिया गया है, तो ऑब्जेक्ट डिफ़ॉल्ट-आरंभीकृत है;

  • यदि T उपयोगकर्ता-प्रदान या हटाए गए डिफ़ॉल्ट निर्माणकर्ता के बिना एक (संभवतः cv-योग्य) वर्ग प्रकार है, तो ऑब्जेक्ट को शून्य-आरंभीकृत किया गया है और डिफ़ॉल्ट-आरंभीकरण के लिए शब्दार्थ अवरोधों की जाँच की जाती है, और यदि T में एक गैर-सामान्य डिफ़ॉल्ट निर्माता है ऑब्जेक्ट डिफ़ॉल्ट-आरंभीकृत है;

  • ...

से [dcl.init.list] :

किसी वस्तु या प्रकार T के संदर्भ की सूची को इस प्रकार परिभाषित किया गया है:

  • ...

  • अन्यथा, यदि इनिशलाइज़र सूची में कोई तत्व नहीं है और T एक डिफ़ॉल्ट कंस्ट्रक्टर के साथ एक वर्ग प्रकार है, तो ऑब्जेक्ट वैल्यू-इनिशियलाइज्ड है।

से विटोरियो रोमियो का जवाब


10

से cppreference :

एकत्रीकरण प्रारंभिक एकत्रीकरण को आरंभ करता है। यह सूची-आरंभीकरण का एक रूप है।

एक समुच्चय निम्नलिखित प्रकारों में से एक है:

[स्निप]

  • वर्ग प्रकार [स्निप], जिसमें है

    • [स्निप] (विभिन्न मानक संस्करणों के लिए विविधताएं हैं)

    • कोई उपयोगकर्ता-प्रदान, विरासत में मिला या स्पष्ट निर्माणकर्ता (स्पष्ट रूप से डिफ़ॉल्ट या हटाए गए निर्माणकर्ता को अनुमति नहीं है)

    • [स्निप] (अधिक नियम हैं, जो दोनों वर्गों पर लागू होते हैं)

इस परिभाषा को देखते हुए, fooएक समुच्चय है, जबकि barऐसा नहीं है (इसमें उपयोगकर्ता-प्रदान किया गया है, गैर-डिफ़ॉल्ट निर्माणकर्ता)।

इसलिए foo, T object {arg1, arg2, ...};समग्र आरंभिक के लिए वाक्यविन्यास है।

कुल आरंभ के प्रभाव हैं:

  • [स्निप] (कुछ विवरण इस मामले के लिए अप्रासंगिक हैं)

  • यदि आरंभिक खंड की संख्या सदस्यों की संख्या से कम है या आरम्भिक सूची पूरी तरह से खाली है, तो शेष सदस्य मूल्य-आरंभिक हैं

इसलिए a.aमूल्य को प्रारंभिक रूप दिया जाता है, जिसका intअर्थ है शून्य प्रारंभिककरण।

इसके लिए bar, T object {};दूसरी ओर मूल्य आरंभीकरण है (वर्ग उदाहरण का, सदस्यों के मूल्य-निर्धारण का मूल्य नहीं!)। चूंकि यह डिफॉल्ट कंस्ट्रक्टर वाला एक क्लास टाइप है, इसलिए डिफॉल्ट कंस्ट्रक्टर को कहा जाता है। डिफॉल्ट कंस्ट्रक्टर जिसे आपने डिफॉल्ट डिफाइन किया है, वह मेंबर्स को इनिशियलाइज़ करता है (मेंबर इनिशियलाइज़र्स नहीं होने के कारण), जो कि int(नॉन-स्टैटिक स्टोरेज के b.bसाथ ) एक अनिश्चित वैल्यू के साथ निकलता है ।

और पॉड-प्रकारों के लिए, डिफ़ॉल्ट आरंभीकरण शून्य-आरंभीकरण है।

नहीं, यह गलत है।


PS आपके प्रयोग और आपके निष्कर्ष के बारे में एक शब्द: यह देखते हुए कि उत्पादन शून्य है इसका मतलब यह नहीं है कि चर शून्य से शुरू किया गया था। कचरा मूल्य के लिए शून्य पूरी तरह से संभव संख्या है।

इसके लिए मैंने पोस्ट करने से पहले शायद 5 ~ 6 बार कार्यक्रम चलाया और अब लगभग 10 बार, हमेशा शून्य है। b थोड़ा बदल जाता है।

यह तथ्य कि मूल्य एक से अधिक बार था, जरूरी नहीं कि इसका मतलब यह है कि इसे या तो आरंभिक किया गया था।

मैंने सेट (CMAKE_CXX_STANDARD 14) के साथ भी प्रयास किया। नतीजा वही हुआ।

यह तथ्य यह है कि परिणाम कई संकलक विकल्पों के साथ समान है इसका मतलब यह नहीं है कि चर आरंभिक है। (हालांकि कुछ मामलों में, बदलते मानक संस्करण बदल सकते हैं कि क्या यह आरंभिक है)।

मैं किसी तरह से अपनी रैम को थोड़ा हिला सकता हूं ताकि अगर वहां शून्य हो, तो यह अब कुछ और होना चाहिए

नॉनज़रो को प्रदर्शित करने के लिए बिना मूल्य वाले मूल्य मान बनाने के लिए C ++ में कोई गारंटीकृत तरीका नहीं है।

केवल यह जानने का तरीका है कि एक चर को आरंभिक किया जाता है, कार्यक्रम की भाषा के नियमों से तुलना की जाती है और यह सत्यापित किया जाता है कि नियम कहते हैं कि यह आरंभिक है। इस मामले a.aमें वास्तव में आरंभिक है।


"डिफॉल्ट कंस्ट्रक्टर जिसे आपने डिफॉल्ट डिफाइन किया है, वह मेंबर्स को इनिशियलाइज़ करता है (मेंबर इनिशियलाइज़र्स नहीं होने के कारण), जो इंट के मामले में इसे एक अनिश्चित मूल्य के साथ छोड़ देता है।" -> एह! "पॉड-प्रकारों के लिए, डिफ़ॉल्ट आरंभीकरण शून्य-आरंभीकरण है।" या मैं गलत हूँ?
बतख डॉजर्स

2
@JoeyMallone POD प्रकारों का डिफ़ॉल्ट आरंभीकरण कोई आरंभीकरण नहीं है।
नाथनऑलिवर

@NathanOliver, फिर मैं और भी भ्रमित हूँ। फिर कैसे aआरंभ किया जाता है। मैं सोच रहा था कि aएक सदस्य POD के लिए डिफ़ॉल्ट आरंभीकृत और डिफ़ॉल्ट आरंभीकरण है, शून्य-आरंभीकरण। क्या aफिर सौभाग्य से हमेशा शून्य ही आ रहा है, चाहे मैं इस कार्यक्रम को कितनी भी बार चलाऊं।
डक डोजर्स

@JoeyMallone Then how come a is initialized.क्योंकि यह आरंभिक मूल्य है। I was thinking a is default initializedयह नहीं।
एरोरिका

3
@JoeyMallone इसके बारे में चिंता न करें। आप C ++ में इनिशियलाइज़ेशन से बाहर एक किताब बना सकते हैं। अगर आपको मौका मिलता है तो यूट्यूब पर CppCon के पास सबसे निराशाजनक (प्रारंभिक रूप में यह कितना बुरा है) के साथ प्रारंभ होने पर कुछ वीडियो हैं। youtube.com/watch?v=7DTlWPgX6zs
Nathanliliver

0

मेह, मैंने आपके द्वारा दिए गए स्निपेट को चलाने की कोशिश की test.cpp, gcc और क्लैंग और कई अनुकूलन स्तरों के माध्यम से:

steve@steve-pc /tmp> g++ -o test.gcc.O0 test.cpp
                                                                              [ 0s828 | Jan 27 01:16PM ]
steve@steve-pc /tmp> g++ -o test.gcc.O2 -O2 test.cpp
                                                                              [ 0s901 | Jan 27 01:16PM ]
steve@steve-pc /tmp> g++ -o test.gcc.Os -Os test.cpp
                                                                              [ 0s875 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.O0
0 32764                                                                       [ 0s004 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.O2
0 0                                                                           [ 0s004 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.Os
0 0                                                                           [ 0s003 | Jan 27 01:16PM ]
steve@steve-pc /tmp> clang++ -o test.clang.O0 test.cpp
                                                                              [ 1s089 | Jan 27 01:17PM ]
steve@steve-pc /tmp> clang++ -o test.clang.Os -Os test.cpp
                                                                              [ 1s058 | Jan 27 01:17PM ]
steve@steve-pc /tmp> clang++ -o test.clang.O2 -O2 test.cpp
                                                                              [ 1s109 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 274247888                                                                   [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.Os
0 0                                                                           [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O2
0 0                                                                           [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 2127532240                                                                  [ 0s002 | Jan 27 01:18PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 344211664                                                                   [ 0s004 | Jan 27 01:18PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 1694408912                                                                  [ 0s004 | Jan 27 01:18PM ]

तो यह वह जगह है जहाँ यह दिलचस्प हो जाता है, यह स्पष्ट रूप से क्लेंग O0 बिल्ड दिखाता है यादृच्छिक संख्या पढ़ रहा है, संभवतः स्टैक स्पेस।

मैंने जल्दी से अपनी आईडीए को देखा कि क्या हो रहा है:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  int result; // eax
  unsigned int v6; // [rsp+8h] [rbp-18h]
  unsigned int v7; // [rsp+10h] [rbp-10h]
  unsigned __int64 v8; // [rsp+18h] [rbp-8h]

  v8 = __readfsqword(0x28u); // alloca of 0x28
  v7 = 0; // this is foo a{}
  bar::bar((bar *)&v6); // this is bar b{}
  v3 = std::ostream::operator<<(&std::cout, v7); // this is clearly 0
  v4 = std::operator<<<std::char_traits<char>>(v3, 32LL); // 32 = 0x20 = ' '
  result = std::ostream::operator<<(v4, v6); // joined as cout << a.a << ' ' << b.b, so this is reading random values!!
  if ( __readfsqword(0x28u) == v8 ) // stack align check
    result = 0;
  return result;
}

अब, क्या करता bar::bar(bar *this)है?

void __fastcall bar::bar(bar *this)
{
  ;
}

हम्म, कुछ नहीं। हमें असेंबली का उपयोग करने का सहारा लेना पड़ा:

.text:00000000000011D0                               ; __int64 __fastcall bar::bar(bar *__hidden this)
.text:00000000000011D0                                               public _ZN3barC2Ev
.text:00000000000011D0                               _ZN3barC2Ev     proc near               ; CODE XREF: main+20p
.text:00000000000011D0
.text:00000000000011D0                               var_8           = qword ptr -8
.text:00000000000011D0
.text:00000000000011D0                               ; __unwind {
.text:00000000000011D0 55                                            push    rbp
.text:00000000000011D1 48 89 E5                                      mov     rbp, rsp
.text:00000000000011D4 48 89 7D F8                                   mov     [rbp+var_8], rdi
.text:00000000000011D8 5D                                            pop     rbp
.text:00000000000011D9 C3                                            retn
.text:00000000000011D9                               ; } // starts at 11D0
.text:00000000000011D9                               _ZN3barC2Ev     endp

तो हाँ, यह सिर्फ कुछ भी नहीं है, जो कि मूल रूप से कंस्ट्रक्टर करता है this = this। लेकिन हम जानते हैं कि यह वास्तव में यादृच्छिक अनइंस्टाल्ड स्टैक एड्रेस लोड कर रहा है और इसे प्रिंट करता है।

क्या होगा यदि हम स्पष्ट रूप से दो संरचनाओं के लिए मूल्य प्रदान करते हैं?

#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b;
};

bar::bar() = default;

int main() {
    foo a{0};
    bar b{0};
    std::cout << a.a << ' ' << b.b;
}

मारो क्लैंग, उफ़्पी:

steve@steve-pc /tmp> clang++ -o test.clang.O0 test.cpp
test.cpp:17:9: error: no matching constructor for initialization of 'bar'
    bar b{0};
        ^~~~
test.cpp:8:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion
      from 'int' to 'const bar' for 1st argument
struct bar {
       ^
test.cpp:8:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion
      from 'int' to 'bar' for 1st argument
struct bar {
       ^
test.cpp:13:6: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
bar::bar() = default;
     ^
1 error generated.
                                                                              [ 0s930 | Jan 27 01:35PM ]

जी ++ के साथ भी ऐसा ही भाग्य:

steve@steve-pc /tmp> g++ test.cpp
test.cpp: In function int main()’:
test.cpp:17:12: error: no matching function for call to bar::bar(<brace-enclosed initializer list>)’
     bar b{0};
            ^
test.cpp:8:8: note: candidate: bar::bar()’
 struct bar {
        ^~~
test.cpp:8:8: note:   candidate expects 0 arguments, 1 provided
test.cpp:8:8: note: candidate: constexpr bar::bar(const bar&)’
test.cpp:8:8: note:   no known conversion for argument 1 from int to const bar&’
test.cpp:8:8: note: candidate: constexpr bar::bar(bar&&)’
test.cpp:8:8: note:   no known conversion for argument 1 from int to bar&&’
                                                                              [ 0s718 | Jan 27 01:35PM ]

तो इसका मतलब यह है कि यह एक प्रत्यक्ष आरंभीकरण है bar b(0), न कि प्रारंभिक इनिशियलाइज़ेशन।

यह शायद इसलिए है क्योंकि यदि आप एक स्पष्ट निर्माण कार्यान्वयन प्रदान नहीं करते हैं तो यह संभवतः एक बाहरी प्रतीक हो सकता है, उदाहरण के लिए:

bar::bar() {
  this.b = 1337; // whoa
}

कंपाइलर स्मार्ट नहीं है ताकि इसे गैर-अनुकूलित चरण में नो-ऑप / इनलाइन कॉल के रूप में घटाया जा सके।

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