Почему я не могу выполнить std :: copy для вектора std :: shared_ptr в C ++ 0x? - PullRequest
2 голосов
/ 10 марта 2011

Я написал класс путей в моей программе для обработки иерархических структур путей.Я решил использовать std :: shared_ptr в качестве стандартного возвращаемого типа для всего класса, так как мне это очень нравится.

Что меня удивило, так это то, что я не смог использовать std :: copy или обычный вектор.insert (v.begin (), v.end ()) для копирования элементов в / из векторов shared_ptr.Почему это так?

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

Когда я попробовал std :: copy (), я получил:

1> C: \ Program Files (x86) \ Microsoft Visual Studio 10.0\ VC \ include \ iterator (21): ошибка C2039: 'const_reference': не является членом 'std :: tr1 :: shared_ptr <_Ty>' 1> с 1> [1>
_Ty = std ::vector> 1>] 1>
BFile.cpp (329): см. ссылку на экземпляр шаблона класса 'std :: back_insert_iterator <_Container>', компилируемый 1> с 1>
[1>
_Container =std :: tr1 :: shared_ptr >> 1>]

Когда я попытался вставить (v.begin (), v.end ()) я получил;

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>          ]

Я не уверен, что понимаю любую из этих ошибок компилятора ... У кого-нибудь еще есть подсказка?

Ответы [ 3 ]

9 голосов
/ 10 марта 2011

Вы пытаетесь создать back_inserter для указателя на вектор, а не на сам вектор. Измените back_inserter(ret) на back_inserter(*ret) (если вы действительно чувствуете необходимость динамически распределять такие векторы).

insert терпит неудачу, потому что вам не хватает аргумента:

ret->insert(ret->begin(), children->begin(), children->end());

Причудливое сообщение об ошибке возникает из-за перегрузки с двумя аргументами insert, причем вторым аргументом является объект для вставки. Компилятор пытается использовать это, но не может преобразовать итератор в тип объекта.

2 голосов
/ 10 марта 2011

std::back_inserter ожидает последовательность, а не std::shared_ptr. Используйте back_inserter(*ret).

Для второго insert() здесь требуется третий параметр: insert(where_to_insert,start,end)

0 голосов
/ 09 июля 2019

рассмотрите возможность использования std :: transform вместо std :: copy.

std::transform(children->begin(), 
               children->end(), 
               back_inserter(ret),
               [](const bfile& in) { return make_shared<bfile>(in); });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...