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

0 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
Run Code Online (Sandbox Code Playgroud)

hmj*_*mjd 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";
Run Code Online (Sandbox Code Playgroud)

resize()不可用,std::reference_wrapper<CanNotCopy>因为它不是默认的可构造的.但是,因为有生命期依赖该解决方案是脆弱的CanNotCopy引用,并int该范围内引用CanNotCopy实例,运行悬空引用的风险.

解决方案是使用std::unique_ptr<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";
Run Code Online (Sandbox Code Playgroud)

尽管如此,对int引用的生命依赖CanNotCopy仍然存在.