首先,我的代码在带有编译器的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
是一个班级。
答案 0 :(得分: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 ++ bug,版本4.5及更高版本。那为什么这是合法的呢?
这是4.5 g ++,clang以及其他编译器之前的错误。该标准的相关部分是3.4.3.1,第1a段:
如果嵌套名称说明符指定了一个类C,并且在嵌套名称说明符之后指定的名称(在C中查找时)是C的注入类名(第9节),则名称为而是考虑命名类C的构造函数。这样的构造函数名称只能在出现在类定义之外的构造函数定义的declarator-id中使用。
换句话说,Obstacle::Obstacle
是非法的,除非在类Obstacle
的构造函数的行外定义中使用。
那么这些编译器如何解析呢?这些编译器仅将Obstacle::Obstacle
视为具有特殊含义,仅适用于构造函数的异常定义。否则,Obstacle::Obstacle
遵循注入的名称规则,但忽略该规则不适用于此的事实。 Obstacle::Obstacle*
不是指向构造函数的指针,因为构造函数没有名称。相反,Obstacle::Obstacle*
表示在Obstacle*
类的上下文中进行评估时Obstacle
的含义。但是在类中,Obstacle*
仍然是指向类Obstacle
的实例的指针。 Obstacle::Obstacle*
只是Obstacle*
,Obstacle::Obstacle::Obstacle*
也是如此,依此类推。堆积尽可能多的Obstacle
s,它仍然只是Obstacle*
。
答案 1 :(得分:1)
您不能将构造函数指针作为存储类型传递。
而不是
std::vector<Obstacle::Obstacle*> obstacles;
试
std::vector<Obstacle*> obstacles;