加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 从std :: set中提取move only类型

发布时间:2020-12-16 10:07:11 所属栏目:百科 来源:网络整理
导读:我有一个std :: set std :: unique_ptr T我想把它移到std :: vector std :: unique_ptr T #include set#include vector#include memoryclass C {};int main(){ std::setstd::unique_ptrconst C s; std::vectorstd::unique_ptrconst C v; std::move(s.begin()
我有一个std :: set< std :: unique_ptr< T>>我想把它移到std :: vector< std :: unique_ptr< T>>

#include <set>
#include <vector>
#include <memory>

class C {};

int main()
{
  std::set<std::unique_ptr<const C>> s;
  std::vector<std::unique_ptr<const C>> v;
  std::move(s.begin(),s.end(),std::back_inserter(v));
}

这会在VS2017上出现以下错误:

error C2280: ‘std::unique_ptr>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)’: attempting to reference a deleted function

我们不能从std :: set中将迭代器移动到非const变量吗?什么可以解决这个问题?

解决方法

为了从集合中提取仅移动元素,唯一的可能性是使用在C 17中添加的 extract方法:

while (!s.empty())
    v.emplace_back(std::move(s.extract(s.begin()).value());

如果你不能使用C 17,只有当你确保它在强加的顺序中保持相同的位置时才允许修改集合的元素(例如使用mutable) – 也就是说,只要它在你的下面具有相同的结果与该集合中的所有其他成员进行比较时的比较器.您可以通过提供一个比较器来执行此操作,该比较器在非空之前对空的唯一指针进行排序(请注意,标准不保证这一点)并在修改后立即擦除修改后的元素:

template<class T> struct MutableWrapper { mutable T value; };
template<class T> struct MutableWrapperCompare {
  bool operator()(MutableWrapper<T> const& lhs,MutableWrapper<T> const& rhs) {
    return lhs.value && rhs.value ? lhs.value < rhs.value : rhs.value;
  }
};

int main()
{
  std::set<MutableWrapper<std::unique_ptr<const C>>,MutableWrapperCompare<std::unique_ptr<const C>>> s;
  std::vector<std::unique_ptr<const C>> v;
  while (!s.empty())
  {
    v.emplace_back(std::move(s.begin()->value));
    s.erase(s.begin());
  }
}

然而,这是相当丑陋和危险的;你最好使用Boost.Container中的boost :: container :: set,它具有C 17提取方法(since 1.62.0;它是was undocumented,但这只是一个疏忽,请注意相应的提取方法是为map和multimap记录的).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读