我已经获得了一些可以在MSVC上编译好的代码,并且我试图让它在Xcode中的Clang上编译。我目前遇到的问题是使用以下typedef重新定义类:
typedef std::map<MyNS::istring, EntityState> Entity;
查看预处理的输出,我可以看到在此typedef之前有class Entity
的两个前向声明。但是,class Entity
的实际定义不在预处理输出中,但它与新实体映射在同一名称空间中(尽管不是MyNS
...)。它是导致此错误的前向声明吗?有没有什么方法可以在MSVC中有效,而不是因为Clang的迂腐而无法工作?
编辑:我没有MSVC可以提供,但是我在这里放了一个片段来展示我得到的那种错误(我已经简化了定义,以便它一切都适合一个小空间)。当我尝试使用Clang编译它时,这会导致同样的错误。这会在MSVC中有效吗?
namespace TheNS {
class Entity;
struct EntityState
{
std::string aString, anotherString;
int anInt;
EntityState() {}
EntityState(std::string a, std::string b, int i)
{
// constructor
}
};
typedef std::map<std::string, EntityState> Entity;
class Entity
{
public:
void SomeFunction();
private:
int m_aVar;
};
}
答案 0 :(得分:1)
是的,这不正确。永远不应该编译,如果它在MSVC上编译 - 可能是编译器的错误。前向声明告诉编译器,TheNS::Entity
将是类而不是其他(不是枚举,联合或typedef)。实际上,您的代码与
class Entity;
typedef int Entity;
当然这是不正确的。
n3337 9.1 / 2
仅由类密钥标识符组成的声明;是重新声明的名称 在当前作用域中或标识符的前向声明作为类名。它引入了类名 进入当前范围。
所以,在此之后
class Entity;
compiles知道,Entity
将被用作类名。此名称可以重新声明为函数(在同一范围内),在这种情况下,当您要使用class Entity
类(或通过typedef重新声明Entity
名称时,您应该使用Entity
在评论中)。
7.1.3 / 6
在给定范围内,typedef说明符不得用于重新定义在其中声明的任何类型的名称 范围指代不同的类型。 [例如:
class complex { /∗ ... ∗/ }; typedef int complex; // error: redifinition
- 结束示例]