C++ 为什么可以';我不能做一个参考向量吗?

C++ 为什么可以';我不能做一个参考向量吗?,c++,vector,reference,stl,container-data-type,C++,Vector,Reference,Stl,Container Data Type,当我这样做时: std::vector<int> hello; std::vector hello; 一切都很好。但是,当我将其作为参考向量时: std::vector<int &> hello; std::vector hello; 我犯了可怕的错误,比如 错误C2528:“指针”:指向引用的指针非法 我想把一堆对结构的引用放到一个向量中,这样我就不必去管指针了。vector为什么要为此大发雷霆?是我使用指针的唯一选项吗? < P>这是C++语言的一个缺

当我这样做时:

std::vector<int> hello;
std::vector hello;
一切都很好。但是,当我将其作为参考向量时:

std::vector<int &> hello;
std::vector hello;
我犯了可怕的错误,比如

错误C2528:“指针”:指向引用的指针非法


我想把一堆对结构的引用放到一个向量中,这样我就不必去管指针了。vector为什么要为此大发雷霆?是我使用指针的唯一选项吗?

< P>这是C++语言的一个缺陷。您不能获取引用的地址,因为这样做会导致引用对象的地址,因此您永远无法获得指向引用的指针
std::vector
使用指向其元素的指针,因此需要能够指向存储的值。你将不得不使用指针来代替它。

就其本质而言,引用只能在创建时设置;i、 例如,以下两行具有非常不同的效果:

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.

但是,创建向量时,无法在创建时为其项赋值。基本上,您只是在制作最后一个示例的一大堆内容。

容器的组件类型(如向量)必须是。引用是不可分配的(当它们被声明时,您只能初始化它们一次,并且您不能让它们在以后引用其他内容)。其他不可分配的类型也不允许作为容器的组件,例如不允许使用向量。

将起作用


Edit:建议使用
std::vector
,这将不起作用,因为您无法默认构造
boost::ref

,正如其他人提到的,您可能最终使用指针向量


但是,您可能需要考虑使用A代替! 是的,您可以,寻找,模仿引用,但可分配,也可以“重置”

Ion Todirel已经提到了使用
std::reference\u 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";
    }             
}
#包括
#包括
#包括
类MyClass{
公众:
void func(){

std::cout正如其他评论所建议的,您仅限于使用指针。 但如果有帮助的话,这里有一种技巧可以避免直接面对指针

您可以执行以下操作:

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]);
}
矢量射线;
int default_item=0;//用于处理超出范围的异常
int&获取项目作为参考(未签名的int-idx){
//处理超出范围的异常
如果(idx>=iarray.size())
返回默认_项;
返回重新解释投射(*iarray[idx]);
}
TL;DR 这样使用:

#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;
}
A
是容器的分配器类型,
m
是分配器实例,
p
*T
类型的指针。有关
可擦除的定义,请参阅


默认情况下,
std::allocator
用作vector的分配器。使用默认分配器,该要求等同于
p->~T()
的有效性(注意
T
是引用类型,
p
是指向引用的指针)。但是,因此表达式的格式不正确。

我想它可以使用void*缓冲区和新位置来实现。这没有多大意义。“语言中的缺陷”太强了。这是设计的。我认为vector不需要与指向元素的指针一起工作。但是需要元素是可分配的。引用不是。你也不能将
sizeof
作为引用。你不需要指向引用的指针,你有引用,如果你确实需要指针,就保留poiINTER本身;这里没有要解决的问题。你是说我不能有向量的向量吗?(我肯定我已经做到了…)是的,std::vector是正确的,std::vector是可赋值的。事实上,这是“实际的”原因。关于T*不可能是T的错误是U&只是违反了T必须可分配的要求的副作用。如果vector能够精确地检查类型参数,那么它可能会说“违反了的要求:T&不可分配”在除交换之外的所有操作中检查可赋值概念对引用都有效。这不再是真的。由于C++11,元素的唯一独立于操作的要求是“可擦除”,而引用则不是。请参阅。“创建向量时,无法在创建时为其项赋值”我不明白你说的这句话是什么意思。什么是“创建时的项”?我可以创建一个空向量。我可以使用.push_back()添加项。您只是指出引用不是默认可构造的。但我肯定可以有不可默认可构造的类的向量。std::vector的元素类型不要求是默认可构造的。您可以编写结构A{A(int);private:A();};vector a;很好-只要您不使用要求它是默认可构造的方法(如v.resize(100);-但是您需要执行v.resize(100,a(1));)以及如何编写这样的push_back()在这种情况下?它仍将使用赋值,而不是构造。James Curran,那里没有默认构造。只将placement news A推回预分配的缓冲区。请参见此处:。注意,我的声明只是vector可以处理非默认可构造类型。当然,我没有声明它可以处理t&(当然不能)。您可以使用std::vector hello;请参阅@amit链接不再有效,官方文档,但您可以使用vector或非默认co
allocator_traits<A>::destroy(m, p)