Why can't I perform a std::copy on a vector of std::shared_ptr's in C++0x?
I've written a path class in my program for handling heirarchical path structures. I decided to use std::shared_ptr as the standard return type for the whole class since I'm getting rather fond it.
What surprised me is that I was unable to use std::copy or the normal vector.insert(v.begin(), v.end()) to copy elements to/from vectors of shared_ptr. Why is this?
shared_ptr<vector<shared_ptr<bfile>>> butils::bfile::search()
{
shared_ptr<vector<shared_ptr<bfile>>> ret(new vector<shared_ptr<bfile>>());
shared_ptr<vector<shared_p开发者_运维问答tr<bfile>>> children = getChildren();
//WTF why don't either of these work?
//std::copy(children->begin(), children->end(), back_inserter(ret));
//ret->insert(children->begin(), children->end());
//I've had to resort to doing this....
for (auto c = children->begin(); c != children->end(); c++)
{
ret->push_back(*c);
auto cChildren = (*c)->search();
for (auto cc = cChildren->begin(); cc != cChildren->end(); cc ++)
{
ret->push_back(*cc);
}
}
return ret;
}
When I tried the std::copy() I got:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\iterator(21): error C2039: 'const_reference' : is not a member of 'std::tr1::shared_ptr<_Ty>' 1> with 1> [ 1>
_Ty=std::vector> 1> ] 1> BFile.cpp(329) : see reference to class template instantiation 'std::back_insert_iterator<_Container>' being compiled 1> with 1> [ 1> _Container=std::tr1::shared_ptr>> 1> ]
When I tried the insert(v.begin(), v.end()) I got;
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(208): error C2664: 'std::tr1::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::_Vector_iterator<_Myvec>' to 'std::nullptr_t'
1> with
1> [
1> _Ty=butils::bfile
1> ]
1> and
1> [
1> _Myvec=std::_Vector_val<std::tr1::shared_ptr<butils::bfile>,std::allocator<std::tr1::shared_ptr<butils::bfile>>>
1> ]
I'm not sure I understand either of these compiler errors... Anyone else have a clue?
You're trying to make a back_inserter
to the pointer to the vector, rather than the vector itself. Change back_inserter(ret)
to back_inserter(*ret)
(if you really feel the need to dynamically allocate vectors like that).
insert
is failing because you're missing an argument:
ret->insert(ret->begin(), children->begin(), children->end());
The bizarre error message there is because there is a 2-argument overload of insert
, with the second argument being an object to insert. The compiler tries to use this, but fails to convert the iterator into the object type.
std::back_inserter
expects a sequence, not a std::shared_ptr
. Use back_inserter(*ret)
.
For the second, insert()
requires a third parameter here: insert(where_to_insert,start,end)
consider using a std::transform in place of std::copy.
std::transform(children->begin(),
children->end(),
back_inserter(ret),
[](const bfile& in) { return make_shared<bfile>(in); });
精彩评论