为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?
Posted
技术标签:
【中文标题】为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?【英文标题】:Why can't I perform a std::copy on a vector of std::shared_ptr's in C++0x?为什么我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy? 【发布时间】:2011-07-12 07:26:10 【问题描述】:我在我的程序中编写了一个路径类来处理层次路径结构。我决定使用 std::shared_ptr 作为整个类的标准返回类型,因为我越来越喜欢它了。
令我惊讶的是,我无法使用 std::copy 或正常的 vector.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 视觉工作室 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>]
当我尝试 insert(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> ]
我不确定我是否理解这些编译器错误...还有其他人有线索吗?
【问题讨论】:
不要太喜欢shared_ptr
,只要没有“共享”所有权,就更喜欢使用unique_ptr
。共享所有权是它自己的一个概念,不应该为了ease而被滥用,因为它有自己的问题(引用循环),只能由内存泄漏工具检测到......经验丰富的程序员。
@Matthieu - 我同意你的观点,尽管考虑到这里的对象只是带有字符串和一些状态的路径对象,很难看出它们如何导致引用循环.
【参考方案1】:
您正在尝试将back_inserter
指向指向向量的指针,而不是向量本身。将back_inserter(ret)
更改为back_inserter(*ret)
(如果你真的觉得需要动态分配这样的向量)。
insert
失败,因为您缺少参数:
ret->insert(ret->begin(), children->begin(), children->end());
出现奇怪的错误消息是因为insert
的两个参数重载,第二个参数是要插入的对象。编译器尝试使用它,但无法将迭代器转换为对象类型。
【讨论】:
【参考方案2】:std::back_inserter
需要一个序列,而不是 std::shared_ptr
。使用back_inserter(*ret)
。
对于第二个,insert()
这里需要第三个参数:insert(where_to_insert,start,end)
【讨论】:
insert(0,start,end) 似乎不起作用,但我认为您的想法是正确的:我猜您的意思是:ret->insert(ret->begin(), children- >开始(),孩子->结束());确实有效,谢谢! 是的 - 抱歉,很快忘记了我们在谈论迭代器,而不是索引。已编辑。 是的,我认为他的意思是ret->begin()
。在此处查看参考:cplusplus.com/reference/stl/vector/insert【参考方案3】:
考虑使用 std::transform 代替 std::copy。
std::transform(children->begin(),
children->end(),
back_inserter(ret),
[](const bfile& in) return make_shared<bfile>(in); );
【讨论】:
以上是关于为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?的主要内容,如果未能解决你的问题,请参考以下文章
关于24c02芯片的程序问题,希望得到帮助解决,下面的程序有啥问题,为啥下载到单片机里面不能运行!
为啥我不能使用'0x80000000'来初始化一个int数组?
为啥在逻辑回归中对 roc_auc 进行评分时,GridSearchCV 不给出具有最高 AUC 的 C