【问题标题】:Visual Studio 2010 Express couldn't compile code with cross referenceVisual Studio 2010 Express 无法通过交叉引用编译代码
【发布时间】:2015-07-14 12:10:52
【问题描述】:

GCC 可以编译下面的代码,但是 VS2010 express 不能:

#include <iostream>
#include <queue>
using namespace std;

struct A
{
  deque<A>::iterator next;
};
int main()
{
  A a;
}

错误信息:

错误 C2027:使用未定义的类型“A”main.cpp(6):参见“A”的声明 main.cpp(7):参见正在编译的类模板实例化“std::deque<_ty>”的引用1> 与 1> [ 1> _Ty=A 1> ]

除了使用指针,还有什么办法可以解决这个问题吗?

【问题讨论】:

  • 错误信息是什么?
  • 错误 C2027: 使用未定义类型 'A' main.cpp(6) : 参见 'A' main.cpp(7) 的声明 : 参见类模板实例化 'std::deque' 正在编译 1> 与 1> [ 1> _Ty=A 1> ]
  • 这真的是 run 与 GCC 吗?
  • 有趣的是,std::unique_ptr&lt;A&gt; next; 作为结构成员在 MSVC2012 上工作。也许与标准库的实现方式有关。我想知道标准是否坚持认为该构造在这种情况下是有效的,而在您的情况下可能不是。
  • C++ 标准要求类型是完整的以实例化标准容器(否则未定义的行为,不需要诊断)。所以你不能在 A 的定义中使用std::deque&lt;A&gt;,即使你前向声明它。由于std::deque&lt;A&gt;的迭代器类型不实例化就无法命名,恐怕这种设计行不通。

标签: c++ visual-studio-2010 cross-reference


【解决方案1】:

正如How come I can use a forward-declared class in a std::vector? 中所讨论的,实例化具有不完整类型的标准容器是未定义的行为。为了能够访问std::deque&lt;A&gt;的迭代器类型,需要实例化这个类,所以你给出的程序有未定义的行为。在这个特定的实例中,在 gcc 中未定义的行为恰好是您所期望的,而 Visual Studio(及其 Dinkumware 标准库实现)恰好无法编译。 Visual Studio 在调试和发布模式下的行为可能不同,因为在调试模式下,容器(和迭代器)要复杂得多,无法检查许多迭代器滥用情况。

我无法快速找到一个引用,允许声明指向元素类型为不完整类型的双端队列迭代器的指针,并且恐怕最有可能用指向迭代器的指针替换迭代器不会做到这一点程序定义(尽管它可能使它在更多环境中工作)。如果您要用指针替换迭代器:这肯定会起作用。我不能告诉你这是否是唯一的解决方案,因为你没有明确说明你试图解决什么问题。可能有一种不同的设计方法来解决您的问题,不需要此成员变量。

【讨论】:

  • 感谢您的回答!任务是设计一个类,该类可以包含对其匹配(通过某些规则)对的引用。有两个双端队列包含我们相互比较并构建对的对象。所以我知道我们可以通过使用指针来完成这些任务,但在我看来像next = &amp;(*(itertor_to_object)); 这样的表达式并不是很好的解决方案:-)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多