c++ - std::vector<T> 编译错误 "T cannot appear in a constant-expression"

标签 c++ g++ llvm

首先,我的代码在带有编译器的 Mac OS X 上编译和运行良好

i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1

但在带有编译器的 Ubuntu 上

g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

它不会编译。

在我的标题中有

std::vector<Obstacle::Obstacle*> obstacles;

在 Ubuntu 中出现以下编译错误:

error: ‘Obstacle::Obstacle’ cannot appear in a constant-expression

关于我需要改变什么才能让它发挥作用的任何想法? 我应该在 Ubuntu 上使用一些神奇的编译标志来使其像在 OS X 上一样工作吗?

谢谢

编辑:Obstacle 是一个类。

最佳答案

显然 Obstacle 只是一个类。

令人惊奇的是,以下代码也有效,已在 g++ 4.2、g++ 4.3、g++ 4.4、clang++ 2.9 和 clang++ 3.1 中测试:

std::vector<Obstacle::Obstacle::Obstacle::Obstacle::Obstacle*> obstacles;

多个版本的g++和多个版本的clang编译了以上。

g++ 4.5 和 4.6 在这个结构上有问题。这看起来像是一个 g++ 错误,版本 4.5 及更高版本。那么为什么这应该是合法的呢?

这是 4.5 之前的 g++、clang 和其他编译器中的错误。该标准的相关部分是 3.4.3.1,第 1a 段:

If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the constructor of class C. Such a constructor name shall be used only in the declarator-id of a constructor definition that appears outside of the class definition.

换句话说,Obstacle::Obstacle 是非法的,除非用于类 Obstacle 的构造函数的异常定义。

那么这些编译器是如何解析的呢?这些编译器将 Obstacle::Obstacle 视为仅在构造函数的外联定义的情况下具有特殊含义。否则,Obstacle::Obstacle 遵循注入(inject)的名称规则,但忽略该规则不适用于此处的事实。 Obstacle::Obstacle* 不是指向构造函数的指针,因为构造函数没有名称。 Obstacle::Obstacle* 表示从类 Obstacle 的上下文中评估时 Obstacle* 表示的任何内容。但是在类内部,Obstacle* 仍然是指向类 Obstacle 的实例的指针。 Obstacle::Obstacle* 只是一个Obstacle*Obstacle::Obstacle::Obstacle* 也是,等等。堆放任意数量的 Obstacle,它仍然只是一个 Obstacle*

关于c++ - std::vector<T> 编译错误 "T cannot appear in a constant-expression",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12883486/

相关文章:

c++ - 2路队列中的访问冲突写入

c++ - 使用 autoexp.dat 和 DLL 扩展 Visual Studio 2003 C++ 调试器

c++ - 使用现代 OpenGL 进行导航的 SDL 键盘和鼠标事件

c++ - frame_dummy 在分析上下文中意味着什么?

c++ - 范围解析运算符

c++ - 用于 LLVM 的 GCC 工具链

xcode - CMake错误: Could not create named generator XCode

c++ - 初始化嵌套模板类

c++ - g++,创建用于分发的静态库

windows - 如何在 Windows 上将 clang 与 mingw-w64 header 一起使用