【问题标题】:Reference of STL vector that contains references to objects generates error in C++. Why?包含对对象的引用的 STL 向量的引用在 C++ 中会产生错误。为什么?
【发布时间】:2013-03-02 19:29:12
【问题描述】:

为什么我不能引用包含对象引用的 std::vector?以下代码在 Visual C++ 2010 中生成编译错误:

void Map::Filter( Object::Type type, std::vector<Object&>& list )
{
  for ( register int y = 0; y < MAP_H; y++ )
    for ( register int x = 0; x < MAP_W; x++ ) {
      if ( under[y][x].GetType() == type )
        list.push_back(under[y][x]);
      if ( above[y][x].GetType() == type )
        list.push_back(above[y][x]);
    }
}

汇总编译错误:

c:\program files\microsoft visual studio 10.0\vc\include\xmemory(137): error C2528: 'pointer' : pointer to reference is illegal
c:\program files\microsoft visual studio 10.0\vc\include\vector(421) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled

我通过从“对象引用向量”切换到“对象指针向量”解决了这个问题。我只是不明白为什么我不能引用引用向量。

【问题讨论】:

  • 引用必须在声明时初始化;指针没有。
  • 为什么是std::vector&lt;Object&amp;&gt; 而不是简单的std::vector&lt;Object&gt;
  • 简短的回答是“因为标准是这样说的”。如果你真的想要,你可以创建一个reference_wrapper 的向量
  • 是的,vector 将复制(或移动,在 C++11 中)对象进/出向量。如果您想避免对象本身被复制/移动,您可以考虑使用 shared_ptr 或 unique_ptr 的向量(仅适用于几种可能的选择)。
  • 如果您对标准中涉及参考规则的部分感兴趣,请参阅 C++11 § 8.3.2,特别是第 5 段:"没有对引用的引用,没有引用数组,也没有指向引用的指针。引用的声明应包含一个初始化程序(8.5.3),除非声明包含显式的外部说明符(7.1.1),是类成员( 9.2) 类定义中的声明,或者是参数或返回类型的声明 (8.3.5);参见 3.1。应初始化引用以引用有效的对象或函数。"

标签: c++ visual-studio-2010 vector stl reference


【解决方案1】:

标准容器使用分配器来分配内存以及构造和销毁元素。分配器要求是为分配器类X 指定的,它负责分配T 类型的对象。 T 类型被指定为“任何非常量、非引用对象类型”(表 27)。所以对引用对象的分配器没有要求。这意味着尝试创建引用类型的容器会直接导致未定义的行为。

表 27 可在 §17.6.3.5 分配器要求中找到:

另一种方法是使用std::reference_wrapperpush_back 元素的向量:

list.push_back(std::ref(under[y][x]));

另一种选择是使用原始指针,或者可能使用World's Dumbest Smart Pointer 的实现。

另外,我建议不要调用您的向量 list - 有一个 std::list 容器类型。它的清单是什么? cats? people? bananas?

【讨论】:

  • 好的,我现在正在使用原始指针,它工作正常,我只是好奇为什么我不使用引用并且我不了解标准。我有一个“对象”对象的容器,即使它是一个向量,我也称它为“列表”,因为称它为“列表”看起来更自然,对我来说,它的名称没有区别。我不会在任何地方的程序中使用 std::list。
猜你喜欢
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2021-06-02
  • 2015-08-05
  • 1970-01-01
相关资源
最近更新 更多