当我这样做时:
std::vector<int> hello;
一切正常。但是,当我将其设为参考向量时:
std::vector<int &> hello;
我收到可怕的错误,例如
错误C2528:“指针”:指向引用的指针不合法
我想将一堆对结构的引用放到一个向量中,这样我就不必插手指针了。为什么vector对此大发脾气?我唯一的选择是使用指针向量吗?
当我这样做时:
std::vector<int> hello;
一切正常。但是,当我将其设为参考向量时:
std::vector<int &> hello;
我收到可怕的错误,例如
错误C2528:“指针”:指向引用的指针不合法
我想将一堆对结构的引用放到一个向量中,这样我就不必插手指针了。为什么vector对此大发脾气?我唯一的选择是使用指针向量吗?
Answers:
容器的组件类型(例如矢量)必须是可分配的。引用是不可分配的(您只能在声明它们时将其初始化一次,并且以后不能使它们引用其他内容)。其他不可分配的类型也不允许作为容器的组件,例如vector<const int>
,不允许。
是的,您可以寻找std::reference_wrapper
模仿参考但可分配的并且也可以“重新安置”
get()
在尝试访问此包装器中的类的实例的方法时,有没有一种方法可以先调用?例如reference_wrapper<MyClass> my_ref(...); my_ref.get().doStuff();
不是很参考。
.get()
。什么timdiels想要的是operator.
; 查看有关此问题的最新建议/讨论。
就其本质而言,只能在创建引用时设置引用。即,以下两行具有非常不同的效果:
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.
但是,创建矢量时,无法在创建时为其分配值。本质上,您只是在编写最后一个示例而已。
离子托迪雷尔已经提到了使用YES的答案std::reference_wrapper
。从C ++ 11开始,我们提供了一种机制,可以使用从中检索对象std::vector
并删除引用std::remove_reference
。以下是使用g++
and clang
with选项编译
-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::remove_reference<>
这里的价值。的要点std::remove_reference<>
是允许您编写“类型T,但如果是类型T,则不作参考”。所以std::remove_reference<MyClass&>::type
是一样的写作MyClass
。
for (MyClass obj3 : vec) std::cout << obj3.getval() << "\n";
(或者,for (const MyClass& obj3: vec)
如果您声明getval()
const,则应如此)。
编辑:建议使用std::vector< boost::ref<int> >
,因为您无法默认构造a,因此该建议不起作用boost::ref
。
resize
。
这是C ++语言的缺陷。您不能使用引用的地址,因为尝试这样做会导致引用对象的地址,因此您永远无法获得指向引用的指针。 std::vector
与指向其元素的指针一起使用,因此需要能够指向要存储的值。您将不得不使用指针。
sizeof
参考。
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;
}
作为标准建议,对于X
包含类型对象的标准容器T
,T
必须Erasable
来自X
。
Erasable
表示以下表达式格式正确:
allocator_traits<A>::destroy(m, p)
A
是容器的分配器类型,m
是分配器实例,并且p
是type的指针*T
。见这里的Erasable
定义。
默认情况下,std::allocator<T>
用作向量的分配器。对于默认分配器,要求等同于的有效性p->~T()
(请注意,T
它是引用类型,并且p
是指向引用的指针)。但是,指向引用的指针是非法的,因此该表达式的格式不正确。
正如其他人提到的那样,您可能最终将使用指针向量。
但是,您可能要考虑使用ptr_vector代替!
正如其他注释所建议的那样,您仅限于使用指针。但是,如果有帮助,这是一种避免直接面对指针的技术。
您可以执行以下操作:
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]);
}
reinterpret_cast
不需要