0

首先,我的代码在带有编译器的 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是一堂课。

4

2 回答 2

4

显然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 及更高版本。那么为什么这应该是合法的呢?

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

如果 nested-name-specifier 指定了一个类 C,并且在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 C 的注入类名(第 9 条),则该名称被认为是命名类 C 的构造函数。这样的构造函数名称只能用于出现在类定义之外的构造函数定义的 declarator-id 中。

换句话说,Obstacle::Obstacle是非法的,除非在 class 的构造函数的外部定义中使用Obstacle

那么这些编译器是如何解析这个的呢?那些编译器Obstacle::Obstacle仅在构造函数的定义异常的情况下才被视为具有特殊含义。否则,Obstacle::Obstacle遵循注入的名称规则,但忽略该规则不适用于此处的事实。Obstacle::Obstacle*不是指向构造函数的指针,因为构造函数没有名称。Obstacle::Obstacle*相反,意味着Obstacle*从类的上下文中评估时的任何方法Obstacle。但在类内部,Obstacle*仍然是一个指向类实例的指针ObstacleObstacle::Obstacle*只是一个Obstacle*, as is Obstacle::Obstacle::Obstacle*, 等等。堆上尽可能多Obstacle的 s,它仍然只是一个Obstacle*.

于 2012-10-14T15:42:36.440 回答
1

您不能将构造函数指针作为存储类型传递。

代替

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

尝试

std::vector<Obstacle*> obstacles;
于 2012-10-14T15:15:35.717 回答