Я написал два класса, и у меня есть проблема, помещая их в вектор:
#include <vector>
#include <iostream>
#include <fstream>
class A
{
public:
std::ofstream filestream;
int aa1;
int aa2;
int aa3;
int aa4;
int aa5;
int aa6;
int aa7;
int aa8;
int aa9;
int aa10;
A() {}
~A() {}
};
class B
{
A aaa;
public:
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
int b8;
int b9;
int b10;
B() {}
~B() {}
};
int main()
{
std::vector<B> vec;
vec.emplace_back();
return 0;
}
Выходное сообщение:
g++ -std=c++11 main.cppIn file included from /usr/include/c++/5/vector:62:0,
from main.cpp:1:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = B; _Args = {B}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:75:18: required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*; bool _TrivialValueTypes = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:126:15: required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*]’
/usr/include/c++/5/bits/stl_uninitialized.h:281:37: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*; _Tp = B]’
/usr/include/c++/5/bits/stl_uninitialized.h:303:2: required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = B*; _ForwardIterator = B*; _Allocator = std::allocator<B>]’
/usr/include/c++/5/bits/vector.tcc:422:8: required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {}; _Tp = B; _Alloc = std::allocator<B>]’
/usr/include/c++/5/bits/vector.tcc:101:23: required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = B; _Alloc = std::allocator<B>]’
main.cpp:46:22: required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: use of deleted function ‘B::B(const B&)’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
main.cpp:24:7: note: ‘B::B(const B&)’ is implicitly deleted because the default definition would be ill-formed:
class B
^
main.cpp:24:7: error: use of deleted function ‘A::A(const A&)’
main.cpp:5:7: note: ‘A::A(const A&)’ is implicitly deleted because the default definition would be ill-formed:
class A
^
main.cpp:5:7: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’
In file included from main.cpp:3:0:
/usr/include/c++/5/fstream:723:7: note: declared here
basic_ofstream(const basic_ofstream&) = delete;
^
Предупреждения и ошибки говорят сами за себя. Но я новичок в перемещении некоторых классов. Как я должен двигаться ofstream
должным образом? Если я определю переместить конструктор, я должен переместить все отдельные элементы из aa1
в aa10
тоже? любой способ обойти это?
По мнению другого сообщений, офстрим должен быть подвижным для моего g++
версия. Почему он не движется неявно?
g++ -v
...
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)
Почему он не движется неявно?
Конструктор перемещения не будет неявно объявлено когда предоставляется пользовательский деструктор:
- нет заявленных пользователем конструкторов копирования;
- нет заявленных пользователем операторов копирования;
- нет никаких заявленных пользователем операторов перемещения;
- нет деструкторов, объявленных пользователем;
Вы можете удалить объявление деструкторов A
а также B
чтобы позволить компилятору сгенерировать конструкторы перемещения для вас, или вы можете определить их явно, используя default
, В обоих случаях конструктор перемещения выполняет полное перемещение по элементам оснований объекта и нестатических элементов. например
class A
{
public:
...
A(A&&) = default;
};
class B
{
public:
...
B(B&&) = default;
};
Добавление к тому, что songyuanyao ответил, это сообщение в совершенстве объясняет все о неявных конструкторах.