“不同类型的Typedef重新定义”错误铿锵工作MSVC代码

问题描述:

我已经给了一些代码编译罚款MSVC,我试图让它在Xcode Clang编译。目前,我正在来这里对面一类正在使用以下的typedef重新定义一个问题:“不同类型的Typedef重新定义”错误铿锵工作MSVC代码

typedef std::map<MyNS::istring, EntityState> Entity; 

在预处理输出看,我可以看到,也有class Entity两个正向声明此之前的typedef。但是,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; 

    }; 

}  
+1

有命名空间,其中存在类实体的向前声明和的typedef上的std ::地图具有相同名称的,是吗? – ForEveR

+0

在其中一个包含的文件中有一个'class Entity'的前向声明,并且在typedef的同一个命名空间中有一个类实体的类定义,但不包含在其中一个包含的文件中(即不显示在预处理输出中)。 – benwad

+1

为什么不发布'Entity'的所有声明(以及声明显示的命名空间)?如果你发布的代码片段可以用clang编译产生你所看到的错误(理想情况下MSVC上没有错误),那更好。虽然在问题中的描述令人费解,但我很困难。 –

是的,这是不正确的。不要编译,如果它编译MSVC - 可能是编译器的一个bug。前向声明告诉编译器,TheNS::Entity将是类,而不是其他(不是枚举,联合或typedef)。真的,你的代码是一样的

class Entity; 
typedef int Entity; 

当然这是不正确的。

n3337 9.1/2

一个声明只包含class-key标识符;是在当前范围内重新声明名称 ,或者将该标识符的前向声明作为类名称进行重新声明。它将类名称 引入当前范围。

所以,这

class Entity; 

编译后知道,那Entity将用作类名。这个名称可以作为函数重新声明(在相同的范围内),在这种情况下,当您想使用Entity类(或者在注释中用typedef重新声明Entity名称)时,应该使用class Entity

7.1.3/6

在给定的范围内,一个typedef说明符不得用于重新定义在 范围中声明是指不同类型的任何类型的名称。 [实施例:

class complex { /∗ ... ∗/ }; 
typedef int complex; // error: redifinition 

- 端示例]

+0

'typedef struct Entity Entity;';) – Xeo