简体   繁体   中英

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_ptr<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); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM