当我这样做的时候:
std::vector<int> hello;
一切都很好。然而,当我把它变成一个引用向量时:
std::vector<int &> hello;
我就会犯可怕的错误
指向引用的指针是非法的
我想把一堆对struct的引用放到一个vector中,这样我就不用管指针了。为什么矢量会为此大发脾气?我唯一的选择是使用指针的向量代替?
当我这样做的时候:
std::vector<int> hello;
一切都很好。然而,当我把它变成一个引用向量时:
std::vector<int &> hello;
我就会犯可怕的错误
指向引用的指针是非法的
我想把一堆对struct的引用放到一个vector中,这样我就不用管指针了。为什么矢量会为此大发脾气?我唯一的选择是使用指针的向量代替?
当前回答
正如其他人所提到的,您可能最终会使用指针向量。
但是,您可能想要考虑使用ptr_vector代替!
其他回答
Boost::ptr_vector<int>将工作。
Edit:是一个建议使用std::vector< boost::ref<int> >,这将不起作用,因为你不能默认构造boost::ref。
容器的组件类型(如向量)必须是可赋值的。引用是不可赋值的(只能在声明时初始化它们一次,以后不能让它们引用其他东西)。其他不可赋值类型也不允许作为容器的组件,例如vector<const int>是不允许的。
没有技术上的原因为什么你不能有一个引用向量,它只是不是API的一部分,大概是为了保持它类似于数组。可以很容易地添加专门化,使用引用,在内部将它们存储为指针,并在API中显示为引用:
vector<int&> ivref;
int i = 42;
ivref.push_back(i); // address of i is stored
ivref.front() = 43; // i is set to 43
ivref.push_back(44); // Marked deleted for rvalue references
ivref.resize(10); // Marked deleted for vector of references
是的,你可以,寻找std::reference_wrapper,它模仿引用,但是可赋值的,也可以“重新定位”
TL;博士
像这样使用std::reference_wrapper:
#include <functional>
#include <string>
#include <vector>
#include <iostream>
int main()
{
std::string hello = "Hello, ";
std::string world = "everyone!";
typedef std::vector<std::reference_wrapper<std::string>> vec_t;
vec_t vec = {hello, world};
vec[1].get() = "world!";
std::cout << hello << world << std::endl;
return 0;
}
Demo
长回答
正如标准所建议的,对于包含类型T的对象的标准容器X, T必须是可从X擦除的。
Erasable表示下面的表达式形式良好:
allocator_traits<A>::destroy(m, p)
A是容器的分配器类型,m是分配器实例,p是类型*T的指针。请参见这里的可擦定义。
默认情况下,std::allocator<T>被用作vector的分配器。对于默认的分配器,这个要求相当于p->~T()的有效性(注意T是一个引用类型,p是指向引用的指针)。但是,指向引用的指针是非法的,因此表达式不是格式良好的。