当我这样做:
std::vector<int> hello;
一切都很好。但是,当我把它作为引用的向量时:
std::vector<int &> hello;
我得到了可怕的错误
错误C2528:'指针':指向引用的指针是非法的
我想把一堆结构的引用放到一个向量中,这样我就不必插入指针了。为什么矢量会对此发脾气?我唯一的选择是使用指针向量吗?
像矢量这样的容器的组件类型必须是assignable。引用不可分配(您只能在声明它们时初始化它们,并且以后不能让它们引用其他内容)。其他不可分配的类型也不允许作为容器的组件,例如vector<const int>
不被允许。
是的你可以,寻找std::reference_wrapper
,模仿参考但可分配,也可以“重新安置”
就其本质而言,引用只能在创建时设置;即,以下两行具有非常不同的效果:
int & A = B; // makes A an alias for B
A = C; // assigns value of C to B.
此外,这是非法的:
int & D; // must be set to a int variable.
但是,在创建矢量时,无法在创建时为其项目指定值。你基本上只是制作了最后一个例子。
Ion Todirel已经使用std::reference_wrapper
提到了答案YES。从C ++ 11开始,我们有一种从std::vector
检索对象的机制,并使用std::remove_reference
删除引用。下面给出了使用g++
和clang
选项编译的示例
-std=c++11
并成功执行。
#include <iostream>
#include <vector>
#include<functional>
class MyClass {
public:
void func() {
std::cout << "I am func \n";
}
MyClass(int y) : x(y) {}
int getval()
{
return x;
}
private:
int x;
};
int main() {
std::vector<std::reference_wrapper<MyClass>> vec;
MyClass obj1(2);
MyClass obj2(3);
MyClass& obj_ref1 = std::ref(obj1);
MyClass& obj_ref2 = obj2;
vec.push_back(obj_ref1);
vec.push_back(obj_ref2);
for (auto obj3 : vec)
{
std::remove_reference<MyClass&>::type(obj3).func();
std::cout << std::remove_reference<MyClass&>::type(obj3).getval() << "\n";
}
}
编辑:是一个建议使用std::vector< boost::ref<int> >
,这将无法正常工作,因为你无法默认构建一个boost::ref
。
这是C ++语言的一个缺陷。您不能获取引用的地址,因为尝试这样做会导致引用对象的地址,因此您永远无法获得指向引用的指针。 std::vector
使用指向其元素的指针,因此需要能够指出存储的值。你将不得不使用指针。
正如其他人所提到的,你最终可能会使用指针向量。
但是,您可能需要考虑使用ptr_vector代替!
像这样使用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;
}
作为standard suggests,对于包含X
类型物体的标准容器T
,T
必须是来自Erasable
的X
。
Erasable
表示以下表达形式良好:
allocator_traits<A>::destroy(m, p)
A
是容器的分配器类型,m
是分配器实例,p
是*T
类型的指针。有关here的定义,请参阅Erasable
。
默认情况下,std::allocator<T>
用作向量的分配器。使用默认分配器,需求等于p->~T()
的有效性(注意T
是引用类型,p
是指向引用的指针)。然而,pointer to a reference is illegal,因此表达形式不佳。
正如其他评论所暗示的那样,你只能使用指针。但如果它有帮助,这里有一种技术可以避免直接面对指针。
您可以执行以下操作:
vector<int*> iarray;
int default_item = 0; // for handling out-of-range exception
int& get_item_as_ref(unsigned int idx) {
// handling out-of-range exception
if(idx >= iarray.size())
return default_item;
return reinterpret_cast<int&>(*iarray[idx]);
}