C++ 在 Vector 中使用不可分配的对象

C++ Use Unassignable Objects in Vector

本文关键字:不可分 可分配 对象 Vector C++      更新时间:2023-10-16

我想在std::vector中存储对象列表,但对象包含引用,无法指定。但是,我可以复制构造对象。

能想到的唯一选择是使用指针来包装对象并在需要分配指针时重新拔插指针,但是这样做的语法会显着降低可读性,尤其是在使用迭代器时,我更喜欢替代方案。

不起作用:

std::vector<MyObject> myVector;
//fill the vector
//...
myVector[1] = object1;

智能指针牺牲了可读性:

std::vector<std::unique_ptr<MyObject>> ptrVector;
//fill the vector
//...
ptrVector[1] = std::unique_ptr<MyObject>(new MyObject(object1));

是否有其他方法可以在std::vector中使用不可分配的对象?

这不是

对您的问题的直接回答,因为我无法提供std::vector的替代品,也无法提供另一种使用它的方式来让您做您需要做的事情。

但是,如果可以修改MyObject的定义,则可以选择更改它,以便它使用std::reference_wrapper而不是传统的引用。这将使MyObject是可分配的。

例:

#include <vector>
#include <functional>
#include <iostream>
struct MyObject
{
  //int &_i;
  std::reference_wrapper<int> _i;
  MyObject(int &i):_i(i) {}
};

int main() {
  std::vector<MyObject> vec;
  int i1 = 3;
  int i2 = 4;
  MyObject c1(i1);
  MyObject c2(i2);
  /* Storing object. */
  vec.push_back(c1);
  /* Assigning to it. */
  vec[0] = c2;
  /* Confirming that it's the correct object now. */
  for (const MyObject &it : vec)
    std::cout << it._i << std::endl;
  /* Modifying the value of its internal reference. */
  vec[0]._i.get() = 5;
  /* Confirming that the original int changed value indeed. */
  std::cout << "i2 == " << i2 << std::endl;
  return 0;
}

警告:现有代码可能已经包含对引用成员(即上面代码中称为_i的成员)的直接赋值。这些赋值旨在更改引用所引用的对象的值。当用std::reference_wrapper替换引用时,所有直接赋值_i = x都必须替换为_i.get() = x,否则程序的语义完全改变。

(编辑)如果使用的引用是常量引用const T&,则可以使用std::reference_wrapper<const T>。使用上面的示例,MyObject的定义将更改为以下内容:

struct MyObject
{
  std::reference_wrapper<const int> _i;
  MyObject(const int &i):_i(i) {}
};

为什么不让"MyObject"可分配呢?您可以覆盖运算符"=",因此"myVector[1] = object1"将是可行的。