如何在C ++ 11中使用带有引用类型实例对象的向量?

时间:2013-06-06 06:19:51

标签: c++ c++11

在C ++ 11中是否可以使std :: vector没有可复制对象(有引用实例)?

struct CanNotCopy {
  int& intref_;
  CanNotCopy(int& i) noexcept : intref_(i) {}
  // How do I make move constructor and operator = ?
};

std::vector<CanNotCopy> hoge; // OK
hoge.resize(10); // default constructor required
int j = 123;
hoge[1] = CanNotCopy(j);  // copy constructor required

4 个答案:

答案 0 :(得分:5)

来自std::vector,描述T

  

对元素施加的要求取决于对容器执行的实际操作。通常,要求元素类型满足MoveConstructible和MoveAssignable的要求,但许多成员函数强加了更严格的要求。

CanNotCopy不可移动或可复制,因此无法用作T

部分解决方案是使用std::reference_wrapper<CanNotCopy>作为元素类型(可复制但不是默认构造):

  

...是一个类模板,它在可复制的可分配对象中包装引用。它经常被用作在标准容器(如std :: vector或std :: pair)中存储引用的机制,它通常不能保存引用。

例如:

std::vector<std::reference_wrapper<CanNotCopy>> hoge;
int j = 19;
CanNotCopy c(j);
hoge.push_back(std::ref(c));
std::cout << hoge[0].get().intref_ << "\n";
<{1}}无法使用

resize(),因为它不是默认构造的。但是,此解决方案很脆弱,因为std::reference_wrapper<CanNotCopy>引用的 CanNotCopy实例中引用的int存在生命依赖性,存在悬空引用的风险。

解决方案是使用std::unique_ptr<CanNotCopy>作为元素类型(可移动且默认可构造):

CanNotCopy

std::vector<std::unique_ptr<CanNotCopy>> hoge; hoge.resize(5); int j = 19; hoge[1].reset(new CanNotCopy(j)); std::cout << hoge[1]->intref_ << "\n"; int引用的生命周期依赖性仍然存在。

答案 1 :(得分:0)

直截了当,允许vector<CanNotCopy>

struct CanNotCopy {
  int& intref_;
  CanNotCopy (CanNotCopy && from) : intref_(from.intref_) { }
};

这当然允许您将对象移入和移出向量,但不能创建副本或创建默认构造的元素。我不知道该类的语义,特别是我不知道intref_的意思。你必须在默认的ctor中初始化它,所以我不能为你写。

答案 2 :(得分:0)

可以通过使用std::optional / boost::optional包装器来实现。第二个要求使用in-place factories来实现所需的行为。

答案 3 :(得分:0)

我有同样的问题得到了很好的回答here:使用std::vector::emplace_back