2013-06-24 3 views
1

У меня возникли проблемы при решении приведенного ниже кода. Я понимаю, что auto_ptr не может использоваться в STL из-за проблемы с копией. Но я не могу решить это, используя C++ 11 unique_ptr. Не могли бы вы помочь мне решить эту проблему?Автоматический указатель (умный) в векторе

Ошибка:

$ g++ -std=c++0x autoinvec.cpp 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h: In copy constructor âvna_data::vna_data(const vna_data&)â: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:214: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:214: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
autoinvec.cpp: In function âint main()â: 
autoinvec.cpp:39: note: synthesized method âvna_data::vna_data(const vna_data&)â first required here 
autoinvec.cpp:39: error: initializing argument 1 of âvoid Usethis::pushmydata(VNADATA)â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h: In member function âvna_data& vna_data::operator=(const vna_data&)â: 
autoinvec.cpp:11: instantiated from âvoid std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:100: instantiated from âvoid std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:747: instantiated from âvoid std::vector<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = vna_data, _Alloc = std::allocator<vna_data>]â 
autoinvec.cpp:27: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:219: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>& std::unique_ptr<_Tp, _Tp_Deleter>::operator=(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/unique_ptr.h:219: error: deleted function âstd::unique_ptr<_Tp, _Tp_Deleter>& std::unique_ptr<_Tp, _Tp_Deleter>::operator=(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = MyClass, _Tp_Deleter = std::default_delete<MyClass>]â 
autoinvec.cpp:11: error: used here 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/vector:69, 
       from autoinvec.cpp:3: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc: In member function âvoid std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = vna_data, _Tp = vna_data, _Alloc = std::allocator<vna_data>]â: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:314: note: synthesized method âvna_data& vna_data::operator=(const vna_data&)â first required here 

Код:

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
auto_ptr<MyClass> ap1; 
auto_ptr<MyClass> ap2; 
string j; 
string m; 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(d); 
} 

int main() { 

Usethis u; 
VNADATA da; 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
da.ap1 = new MyClass(); 
da.ap2 = new MyClass(); 
u.pushmydata(da); 

return 0; 
} 

Код с unique_ptr:

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
unique_ptr<MyClass> ap1; 
unique_ptr<MyClass> ap2; 
string j; 
string m; 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(move(d)); 
} 

int main() { 

Usethis u; 
VNADATA da; 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
da.ap1.reset(new MyClass); 
da.ap2.reset(new MyClass); 
u.pushmydata(da); 

return 0; 
} 
+3

Ваш код, как написано, использует 'auto_ptr', а не' unique_ptr'. Разве вы уже не сказали, что понимаете, что это не сработает? – jogojapan

+0

Да, но с unique_ptr я думаю, что мое использование неверно и дает мне ошибку. Я надеялся, что кто-то может дать мне предложения по базовому коду с помощью unique_ptr или другого. – user1663533

+1

Пожалуйста, предоставьте код с вашей попыткой решить проблему с помощью 'unique_ptr', иначе любой ответ попытается дать вам некоторое' auto_ptr' решение, которое подвержено ошибкам, как вы уже поняли. Другими словами, вы должны попытаться решить проблему 'unique_ptr', а не' auto_ptr'. –

ответ

0

Я думаю, что вы будете делать вашу жизнь проще, если вы используете std::shared_ptr и std::make_shared.

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 

class MyClass { 
public: 
MyClass() { cout << "Myclass const" << endl; } 
}; 

typedef struct vna_data { 
string i; 
shared_ptr<MyClass> ap1; 
shared_ptr<MyClass> ap2; 
string j; 
string m; 
vna_data(shared_ptr<MyClass> ap1, shared_ptr<MyClass> ap2) : ap1(ap1), ap2(ap2) { 

} 
} VNADATA; 

class Usethis { 
vector<VNADATA> _data; 
public: 
Usethis() {cout << "Usethis const" << endl; } 
void pushmydata (VNADATA d); 
}; 

void Usethis::pushmydata(VNADATA d) { 
_data.push_back(d); 
} 

int main() { 

Usethis u; 
VNADATA da(std::make_shared<MyClass>(), std::make_shared<MyClass>()); 
da.i = "one"; 
da.j = "two"; 
da.m = "three"; 
u.pushmydata(da); 
} 
1

unique_ptr является перемещаемым, но не копируемыми. Ваш метод Usethis::pushmydata принимает значение VNADATA по значению, которое пытается скопировать unique_ptr, поэтому он ломается.

Точки компилятора вы к использованию метода pushmydata на линии 39:

autoinvec.cpp: In function int main(): 
autoinvec.cpp:39: note: synthesized method vna_data::vna_data(const vna_data&) first required here 
autoinvec.cpp:39: error: initializing argument 1 of void Usethis::pushmydata(VNADATA) 

Чтобы исправить проблему, изменить подпись Usethis::pushmydata к;

void Usethis::pushmydata(VNADATA&& d) 
0

Последняя строка:

u.pushmydata(da); 

потребует копию. Вы должны использовать перемещение здесь так же, как и раньше:

u.pushmydata(std::move(da)); 

и он скомпилирует код.

Смежные вопросы