2013-09-06 11 views
12

हाय के बजाय प्रति का उपयोग करता है मैं जीसीसी 4.7 का उपयोग कर एक noexcept चाल निर्माता के साथ एक वर्ग फू बनाया है और 2 के लिए वेक्टर आरक्षित आकार सेट तो यह जब 3 आइटम जोड़ने आकार पुनः आवंटित करने के लिए होता है। ऐसा लगता है कि यह करने के दौरान यह चालक कन्स्ट्रक्टर की बजाय कॉपी कन्स्ट्रक्टर को बुला रहा है। क्या मुझसे कोई चूक हो रही है?वेक्टर पुनः आबंटन चाल निर्माता

#include <vector> 
#include <iostream> 

class Foo 
{ 
    public: 
    Foo(int x) : data_(x) 
    { 
    std::cout << " constructing " << std::endl; 
    } 

    ~Foo() 
    { 
    std::cout << " destructing " << std::endl; 
    } 

    Foo& operator=(const Foo&) = default; 
    Foo& operator=(Foo&&) = default; 

    Foo(Foo&& other) noexcept : data_(std::move(other.data_)) 
    { 
    std::cout << " Move constructing " << std::endl; 
    } 

    Foo(const Foo& other) noexcept : data_(other.data_) 
    { 
    std::cout << " Copy constructing " << std::endl; 
    } 

    private: 
    int data_; 
}; 


int main (int argc, char *argv[]) 
{ 
    std::vector<Foo> v; 
    v.reserve(2); 
    v.emplace_back(1); 
    std::cout << "Added 1" << std::endl; 
    v.emplace_back(2); 
    std::cout << "Added 2" << std::endl; 
    v.emplace_back(3); 
    std::cout << "Added 3" << std::endl; 
    std::cout << "v size: " << v.size() << std::endl; 
} 

उत्पादन:

constructing 
Added 1 
constructing 
Added 2 
constructing 
Copy constructing 
Copy constructing 
destructing 
destructing 
Added 3 
v size: 3 
destructing 
destructing 
destructing 
+1

मेरे बजना निर्माण प्रतिलिपि ctor एक बार सक्रिय नहीं है। एक स्मार्ट जीसीसी प्राप्त करें? – WhozCraig

+1

यह काम करता है के रूप में उम्मीद जीसीसी 4.8.1 के साथ (जो vector' चाल निर्माता कहता है ')। –

+2

यह [4.8.1 जीसीसी] के साथ ठीक काम करता है (http://ideone.com/SXoMw2)। 4.7 – Angew

उत्तर

13

इसके साथ दोनों जीसीसी 4.7 और 4.8 के साथ एक सा संवारता बाद, ऐसा लगता है कि यह वास्तव में 4.7 में एक बग, जो केवल प्रकट होता है जब क्लास 'नाशक है नहीं चिह्नित noexcept:

struct Foo { 
    Foo() {} 
    ~Foo() noexcept {} 
    Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; } 
    Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; } 
}; 

int main() { 
    std::vector<Foo> v; 
    v.reserve(2); 
    v.emplace_back(); 
    v.emplace_back(); 
    v.emplace_back(); 
} 

जीसीसी 4.7 प्रदर्शित करता है:

move constructor 
move constructor 

अगर हम नाशक से noexcept निकालें:

struct Foo { 
    Foo() {} 
    ~Foo() {} 
    Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; } 
    Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; } 
}; 

जीसीसी 4.7 प्रदर्शित करता है:

copy constructor 
copy constructor 

जीसीसी 4.8 दोनों ही मामलों में कदम निर्माता का उपयोग करता है।

+9

+1 [बग मिला] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56191)। 'G ++ 4.7 नियम लागू नहीं करता है कि विनाशक अस्वीकार्य हैं, इसलिए आपको विनाशक पर एक स्पष्ट अस्वीकरण विनिर्देश जोड़ने की आवश्यकता है। जीसीसी 4.8 सही ढंग से सी ++ 11.' द्वारा आवश्यक विनाशक को छोड़ देता है –

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