为什么我不能做一个参考向量?

时间:2020-12-26 21:01:16

When I do this:

当我这样做:

std::vector<int> hello;

Everything works great. However, when I make it a vector of references instead:

一切都很好。然而,当我把它作为参考向量时:

std::vector<int &> hello;

I get horrible errors like "error C2528: 'pointer' : pointer to reference is illegal".

我得到了可怕的错误,比如“error C2528: 'pointer':指针指向引用是非法的”。

I want to put a bunch of references to structs into a vector, so that I don't have to meddle with pointers. Why is vector throwing a tantrum about this? Is my only option to use a vector of pointers instead?

我想把一堆关于结构的引用放到一个向量中,这样我就不用去管指针了。为什么向量会对这个发脾气?我唯一的选择是使用指针向量吗?

8 个解决方案

#1


260  

The component type of containers like vectors must be assignable. References are not assignable (you can only initialize them once when they are declared, and you cannot make them reference something else later). Other non-assignable types are also not allowed as components of containers, e.g. vector<const int> is not allowed.

像向量这样的容器的组件类型必须是可赋值的。引用是不可赋值的(您只能在声明它们时初始化它们一次,并且以后不能使它们引用其他东西)。其他不可赋值类型也不允许作为容器的组成部分,例如向量 是不允许的。

#2


81  

yes you can, look for std::reference_wrapper, that mimics a reference but is assignable and also can be "reseated"

是的,可以查找std::reference_wrapper,它模拟了一个引用,但它是可赋值的,而且它也是可重定位的

#3


26  

By their very nature, references can only be set at the time they are created; i.e., the following two lines have very different effects:

根据它们的性质,只能在创建引用时设置引用;即。,以下两行有非常不同的效果:

int & A = B;   // makes A an alias for B
A = C;         // assigns value of C to B.

Futher, this is illegal:

进一步,这是非法的:

int & D;       // must be set to a int variable.

However, when you create a vector, there is no way to assign values to it's items at creation. You are essentially just making a whole bunch of the last example.

然而,当您创建一个矢量时,没有办法为它的创建项指定值。你实际上就是在做最后一个例子。

#4


18  

Ion Todirel already mentioned an answer YES using std::reference_wrapper. Since C++11 we have a mechanism to retrieve object from std::vector and remove the reference by using std::remove_reference. Below is given an example compiled using g++ and clang with option
-std=c++11 and executed successfully.

Ion Todirel已经使用std::reference_wrapper给出了一个肯定的答案。由于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";
    }             
}

#5


14  

boost::ptr_vector<int> will work.

boost::ptr_vector < int >。

Edit: was a suggestion to use std::vector< boost::ref<int> >, which will not work because you can't default-construct a boost::ref.

编辑:是使用std::vector< boost::ref >的建议,这将不起作用,因为您不能默认构造boost::ref。

#6


11  

It's a flaw in the C++ language. You can't take the address of a reference, since attempting to do so would result in the address of the object being referred to, and thus you can never get a pointer to a reference. std::vector works with pointers to its elements, so the values being stored need to be able to be pointed to. You'll have to use pointers instead.

这是c++语言的一个缺陷。您不能获取引用的地址,因为这样做会导致被引用对象的地址,因此您永远无法获得指向引用的指针。vector使用指向其元素的指针,所以要存储的值必须能够被指向。你必须使用指针。

#7


2  

As other have mentioned, you will probably end up using a vector of pointers instead.

正如前面提到的,您可能最终会使用一个指针矢量。

However, you may want to consider using a ptr_vector instead!

但是,您可能需要考虑使用ptr_vector !

#8


0  

As the other comments suggest, you are confined to using pointers. But if it helps, here is one technique to avoid facing directly with pointers.

正如其他评论所指出的,您只能使用指针。但是如果有帮助的话,这里有一种技术可以避免直接面对指针。

You can do something like the following:

你可以这样做:

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]);
}

#1


260  

The component type of containers like vectors must be assignable. References are not assignable (you can only initialize them once when they are declared, and you cannot make them reference something else later). Other non-assignable types are also not allowed as components of containers, e.g. vector<const int> is not allowed.

像向量这样的容器的组件类型必须是可赋值的。引用是不可赋值的(您只能在声明它们时初始化它们一次,并且以后不能使它们引用其他东西)。其他不可赋值类型也不允许作为容器的组成部分,例如向量 是不允许的。

#2


81  

yes you can, look for std::reference_wrapper, that mimics a reference but is assignable and also can be "reseated"

是的,可以查找std::reference_wrapper,它模拟了一个引用,但它是可赋值的,而且它也是可重定位的

#3


26  

By their very nature, references can only be set at the time they are created; i.e., the following two lines have very different effects:

根据它们的性质,只能在创建引用时设置引用;即。,以下两行有非常不同的效果:

int & A = B;   // makes A an alias for B
A = C;         // assigns value of C to B.

Futher, this is illegal:

进一步,这是非法的:

int & D;       // must be set to a int variable.

However, when you create a vector, there is no way to assign values to it's items at creation. You are essentially just making a whole bunch of the last example.

然而,当您创建一个矢量时,没有办法为它的创建项指定值。你实际上就是在做最后一个例子。

#4


18  

Ion Todirel already mentioned an answer YES using std::reference_wrapper. Since C++11 we have a mechanism to retrieve object from std::vector and remove the reference by using std::remove_reference. Below is given an example compiled using g++ and clang with option
-std=c++11 and executed successfully.

Ion Todirel已经使用std::reference_wrapper给出了一个肯定的答案。由于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";
    }             
}

#5


14  

boost::ptr_vector<int> will work.

boost::ptr_vector < int >。

Edit: was a suggestion to use std::vector< boost::ref<int> >, which will not work because you can't default-construct a boost::ref.

编辑:是使用std::vector< boost::ref >的建议,这将不起作用,因为您不能默认构造boost::ref。

#6


11  

It's a flaw in the C++ language. You can't take the address of a reference, since attempting to do so would result in the address of the object being referred to, and thus you can never get a pointer to a reference. std::vector works with pointers to its elements, so the values being stored need to be able to be pointed to. You'll have to use pointers instead.

这是c++语言的一个缺陷。您不能获取引用的地址,因为这样做会导致被引用对象的地址,因此您永远无法获得指向引用的指针。vector使用指向其元素的指针,所以要存储的值必须能够被指向。你必须使用指针。

#7


2  

As other have mentioned, you will probably end up using a vector of pointers instead.

正如前面提到的,您可能最终会使用一个指针矢量。

However, you may want to consider using a ptr_vector instead!

但是,您可能需要考虑使用ptr_vector !

#8


0  

As the other comments suggest, you are confined to using pointers. But if it helps, here is one technique to avoid facing directly with pointers.

正如其他评论所指出的,您只能使用指针。但是如果有帮助的话,这里有一种技术可以避免直接面对指针。

You can do something like the following:

你可以这样做:

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]);
}