Hãy xem xét đoạn mã sau C++ 11:Tại sao mã này sẽ không biên dịch nếu destructor được khai báo?
#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();
}
Nếu bất kỳ của các dòng tuyên bố destructor trên mã trước đây là không chú thích, mã này sẽ không biên dịch. Trình biên dịch phàn nàn về bản sao construtor của std::thread
bị xóa. Nhưng std::vector::emplace_back
sẽ không sử dụng hàm tạo bản sao, vì vậy, tại sao nó không thành công? Và tại sao heck đề cập đến các destructor vấn đề?
đầu ra GCC (~A() {};
không chú thích):
$ 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;
^
Clang đầu ra (~A() {};
không chú thích):
$ 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.
Đặc điểm kỹ thuật rõ ràng của trình phá hủy ngăn cản trình dịch chuyển-trình biên dịch tổng hợp. Bạn sẽ phải thêm một tài khoản theo cách thủ công. – 0x499602D2
Cảm ơn. Thêm 'A (A && o) = mặc định;' đã giải quyết được vấn đề của tôi. – lvella