Reputation: 95
I am having trouble in solving the below code. I understand auto_ptr cannot be used in STL due to the copy issue. But I am not able to solve this using the C++11 unique_ptr as well. Can you please help me solve this?
Error:
$ 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
Code:
#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;
}
Code with 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;
}
Upvotes: 1
Views: 779
Reputation: 17183
Your last line:
u.pushmydata(da);
would require copy. You shall use move here just as you did earlier:
u.pushmydata(std::move(da));
and it makes the code compile.
Upvotes: 0
Reputation: 13192
unique_ptr
is moveable but not copyable. Your Usethis::pushmydata
method takes a VNADATA
by value, which tries to copy the unique_ptr
, so it breaks.
The compiler points you to the use of the pushmydata method on line 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)
To fix your problem, change the signature of Usethis::pushmydata
to;
void Usethis::pushmydata(VNADATA&& d)
Upvotes: 1
Reputation: 19252
I think you will make your life easier if you use std::shared_ptr
and 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);
}
Upvotes: 0