पुराने एलोक्टेक्टर :: कंस्ट्रक्शन और नए और स्पष्ट कंस्ट्रक्टर में क्या अंतर है?


15

जैसा कि मुझे पता std::allocator<T>::constructहै कि C ++ के पुराने संस्करण पर केवल दो पैरामीटर हैं; पहला कच्चे, संयुक्त-निर्मित मेमोरी के लिए एक संकेतक है जिसमें हम प्रकार की एक वस्तु का निर्माण करना चाहते हैं Tऔर दूसरा उस वस्तु को शुरू करने के लिए तत्व प्रकार का एक मूल्य है। तो कॉपी-कंस्ट्रक्टर को आमंत्रित किया जाता है:

struct Foo {
    Foo(int, int) { cout << "Foo(int, int)" << endl; }
    /*explicit*/ Foo(int) { cout << "Foo(int)" << endl; }
    Foo(const Foo&) { cout << "Foo(const Foo&)" << endl; }
};

int main(int argc, char* argv[]) {


    allocator<Foo> a;
    Foo* const p = a.allocate(200, NULL); // second parameter is required on C++98 but on C++11 it is optional
//  Foo* const p = a.allocate(200); // works fine on C++11 but not on C++98

    a.construct(p, 5, 7); // works on C++ 11 and up but not C++98
    a.construct(p, 10);// works on both
    a.destroy(p);
    a.destroy(p + 1);
    a.deallocate(p, 200);



    std::cout << std::endl;
}
  • क्यों C ++ 98 a.construct(p, 10)पर कॉपी कंस्ट्रक्टर को कॉल किया जाता है, लेकिन C ++ 11 और इसके बाद के संस्करण को केवल एक कॉन्टेक्टर लेने वाले कंस्ट्रक्टर को कॉल किया जाता है?

  • सी ++ पर कुछ कॉपी-इलिजन अनुकूलन भले ही निर्माता की वजह से 11 इसका मतलब यह है Foo(int)है explicitइस तरह के फोन पर काम करता है: a.construct(p, 5)सी पर काम करता है ++ 11 भी निर्माता है explicitहै की यह सी ++ 98 यदि पर काम करता है नहीं पड़ता कि मुझे यकीन है Foo(int)है explicit

  • यदि ऐसा है तो अगर मैं उस कथन को किसी प्रकार के copy-elisionअनुकूलन अनुकूलन को संकलित करता हूं तो संकलक विफल हो जाएगा? धन्यवाद।


3
संक्षिप्त उत्तर: C ++ 11 तक, कोई पूर्ण फ़ॉवर्सिंग नहीं थी । नीचे दिए गए विवरण @flyx। ध्यान दें कि इसमें कोई कॉपी एलिसन शामिल नहीं है (कोई पास-बाय-वैल्यू या रिटर्न-बाय-वैल्यू) नहीं है।
डैनियल लैंगर

जवाबों:


13

इसका कारण यह है कि construct C ++ 11 में बदले जाने की घोषणा :

void construct( pointer p, const_reference val );  (1)  (until C++11)
template< class U, class... Args >
void construct( U* p, Args&&... args );            (2)  (since C++11)

पहली घोषणा को कॉपी कंस्ट्रक्टर कहते हैं, जबकि दूसरी घोषणा एक कंस्ट्रक्टर को कहते हैं जो दी गई दलीलों की सूची से मेल खाता है। यह कॉपी कंस्ट्रक्टर हो सकता है, लेकिन एक अन्य कंस्ट्रक्टर भी जैसा कि आपने अपने कोड में देखा था।

a.construct(p, 10)C ++ 98 में कॉपी कंस्ट्रक्टर को कॉल करता है क्योंकि 10यह स्पष्ट रूप Fooसे Foo(int)कंस्ट्रक्टर के माध्यम से परिवर्तित होता है । सी ++ 11 में यह रूपांतरण आवश्यक नहीं है क्योंकि एक मिलान निर्माणकर्ता है जो एक लेता है int(बिल्कुल निर्माणकर्ता जिसका उपयोग C ++ 98 में परिवर्तित करने के लिए किया गया था)। यही कारण है कि जब आप जोड़ते हैं तो कोड C ++ 98 में काम नहीं करता है explicit- यह तब 10तक परिवर्तित नहीं कर सकता है Foo

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