首页 >后端开发 >C++ >如何在 C 中初始化具有仅移动类型的向量?

如何在 C 中初始化具有仅移动类型的向量?

Linda Hamilton
Linda Hamilton原创
2025-01-01 08:55:09867浏览

How Can I Initialize a Vector with Move-Only Types in C  ?

可以实现仅移动类型的向量初始化吗?

尝试使用唯一指针(移动)初始化向量时会出现问题-仅限类型。当遇到这样的代码时:

#include <vector>
#include <memory>

using move_only = std::unique_ptr<int>;
std::vector<move_only> v { move_only(), move_only(), move_only() };

GCC 4.7 尽力从初始化列表中复制唯一指针,由于 std::unique_ptr 的仅移动性质,导致不允许的复制尝试.

GCC 的方法:是吗有缺陷吗?

考虑到唯一指针是不可复制的,GCC 复制指针的意图是正确的。但是,它使用的方法(从初始值设定项列表进行复制)会触发已删除的复制构造函数。

使用 Make Move Iterator 的替代解决方案

处理仅移动类型向量初始化,首选方法涉及利用 make move 迭代器:

#include <iterator>
#include <vector>
#include <memory>

int main(){
  using move_only = std::unique_ptr<int>;
  move_only init[] = { move_only(), move_only(), move_only() };
  std::vector<move_only> v{std::make_move_iterator(std::begin(init)),
      std::make_move_iterator(std::end(init))};
}

从 make move 获得的迭代器迭代器在解引用时促进元素的移动,解决复制问题。

使用模板包装器的替代解决方案

另一种方法涉及使用具有右值引用语义的模板包装器:

// Helper type for converting rvalues to lvalues
template<class T>
struct rref_wrapper
{
  explicit rref_wrapper(T&& v)
    : _val(std::move(v)) {}

  explicit operator T() const{
    return T{ std::move(_val) };
  }

private:
  T&amp;&amp; _val;
};

// Helper function to convert rvalues to rref_wrappers
template<class T>
typename std::enable_if<
  !std::is_lvalue_reference<T>::value,
  rref_wrapper<T>
>::type rref(T&& v){
  return rref_wrapper<T>(std::move(v));
}

// Helper function to delete lvalue references
template<class T>
void rref(T&amp;) = delete;

虽然此解决方案提供了一种从概念上将右值转换为左值,由于其波动性,谨慎行事至关重要。可以通过两步过程实现更简洁的初始化:

std::initializer_list<rref_wrapper<move_only>> il{ rref(move_only()),
                                                   rref(move_only()),
                                                   rref(move_only()) };
std::vector<move_only> v(il.begin(), il.end());

以上是如何在 C 中初始化具有仅移动类型的向量?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn