2014-05-09 6 views
6

पर विचार करें निम्नलिखित सी ++ 11 कोड:यदि विनाशक घोषित किया गया है तो यह कोड संकलित क्यों नहीं होगा?

#include <thread> 
#include <vector> 

struct A { 
    A() {} 

    //virtual ~A() = default; 
    //~A() = default; 
    //~A() {}; 

    std::thread t; 
}; 

int main() 
{ 
    std::vector<A> v; 
    v.emplace_back(); 
} 

तो लाइनों पिछले कोड पर नाशक घोषित करने के किसी भी uncommented है, इस कोड को संकलित नहीं होंगे। संकलक std::thread की प्रतिलिपि बनाने वाले प्रतिलिपि के बारे में शिकायत करता है। लेकिन std::vector::emplace_back को कॉपी कन्स्ट्रक्टर का कोई उपयोग नहीं करना चाहिए, तो, यह क्यों विफल रहता है? और विनाशक का जिक्र क्यों मायने रखता है?

जीसीसी निर्गम (~A() {}; uncommented):

$ g++ --std=c++11 -o test test.cpp 
In file included from /usr/include/c++/4.8/memory:64:0, 
       from /usr/include/c++/4.8/thread:40, 
       from test.cpp:1: 
/usr/include/c++/4.8/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = A; _Args = {A}]’: 
/usr/include/c++/4.8/bits/stl_uninitialized.h:75:53: required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; bool _TrivialValueTypes = false]’ 
/usr/include/c++/4.8/bits/stl_uninitialized.h:117:41: required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*]’ 
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; _Tp = A]’ 
/usr/include/c++/4.8/bits/stl_uninitialized.h:281:69: required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = A*; _ForwardIterator = A*; _Allocator = std::allocator<A>]’ 
/usr/include/c++/4.8/bits/vector.tcc:415:43: required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {}; _Tp = A; _Alloc = std::allocator<A>]’ 
/usr/include/c++/4.8/bits/vector.tcc:101:54: required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = A; _Alloc = std::allocator<A>]’ 
test.cpp:17:17: required from here 
/usr/include/c++/4.8/bits/stl_construct.h:75:7: error: use of deleted function ‘A::A(const A&)’ 
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 
    ^
test.cpp:4:8: note: ‘A::A(const A&)’ is implicitly deleted because the default definition would be ill-formed: 
struct A { 
     ^
test.cpp:4:8: error: use of deleted function ‘std::thread::thread(const std::thread&)’ 
In file included from test.cpp:1:0: 
/usr/include/c++/4.8/thread:126:5: error: declared here 
    thread(const thread&) = delete; 
    ^

बजना निर्गम (~A() {}; uncommented):

$ clang++ --std=c++11 -o test test.cpp 
In file included from test.cpp:1: 
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:40: 
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/memory:64: 
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_construct.h:75:38: error: 
     call to implicitly-deleted copy constructor of 'A' 
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 
            ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:75:8: note: 
     in instantiation of function template specialization 
     'std::_Construct<A, A>' requested here 
       std::_Construct(std::__addressof(*__cur), *__first); 
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:117:2: note: 
     in instantiation of function template specialization 
     'std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<A *>, 
     A *>' requested here 
     __uninit_copy(__first, __last, __result); 
     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:258:19: note: 
     in instantiation of function template specialization 
     'std::uninitialized_copy<std::move_iterator<A *>, A *>' requested here 
    { return std::uninitialized_copy(__first, __last, __result); } 
       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:279:19: note: 
     in instantiation of function template specialization 
     'std::__uninitialized_copy_a<std::move_iterator<A *>, A *, A>' requested 
     here 
     return std::__uninitialized_copy_a 
       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/vector.tcc:413:15: note: 
     in instantiation of function template specialization 
     'std::__uninitialized_move_if_noexcept_a<A *, A *, std::allocator<A> >' 
     requested here 
       = std::__uninitialized_move_if_noexcept_a 
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/vector.tcc:101:4: note: 
     in instantiation of function template specialization 'std::vector<A, 
     std::allocator<A> >::_M_emplace_back_aux<>' requested here 
      _M_emplace_back_aux(std::forward<_Args>(__args)...); 
     ^
test.cpp:17:4: note: in instantiation of function template specialization 
     'std::vector<A, std::allocator<A> >::emplace_back<>' requested here 
     v.emplace_back(); 
     ^
test.cpp:11:14: note: copy constructor of 'A' is implicitly deleted because 
     field 't' has a deleted copy constructor 
     std::thread t; 
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:126:5: note: 
     'thread' has been explicitly marked deleted here 
    thread(const thread&) = delete; 
    ^
1 error generated. 
+5

विनाशक का स्पष्ट विनिर्देश संकलक-संश्लेषित चाल-निर्माता को रोकता है। आपको मैन्युअल रूप से एक जोड़ना होगा। – 0x499602D2

+0

धन्यवाद। 'ए (ए & ओ ओ) = डिफ़ॉल्ट जोड़ना;' मेरी समस्या हल हो गई। – lvella

उत्तर

6

(टिप्पणियों से लिया जवाब, कोई क्रेडिट मेरे द्वारा लिया गया)

तो एक विनाशक को मैन्युअल रूप से घोषित किया जाता है, संकलन करते समय डिफ़ॉल्ट चाल कन्स्ट्रक्टर नहीं बनाया जाता है। उपयोग किए जाने वाले डिफ़ॉल्ट चाल कन्स्ट्रक्टर को मजबूर करने से यह ठीक हो जाएगा:

A(A&& o) = default; 
+2

यह उल्लेखनीय हो सकता है कि कोड काम करेगा यदि ए के पास std :: thread के बजाय एक प्रतिलिपि सदस्य था क्योंकि ए के प्रतिलिपि को उस मामले में पूरी तरह से हटाया नहीं जाएगा (मैं अपने फोन से जवाब संपादित नहीं करना चाहता)। – jrok

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