工作 MSVC 代码的 Clang 中的“使用不同类型的 Typedef 重新定义”错误
Posted
技术标签:
【中文标题】工作 MSVC 代码的 Clang 中的“使用不同类型的 Typedef 重新定义”错误【英文标题】:"Typedef redefinition with different types" error in Clang on working MSVC code 【发布时间】:2012-10-02 09:37:09 【问题描述】:我得到了一些在 MSVC 上编译良好的代码,我正试图让它在 Xcode 中的 Clang 上编译。我目前遇到了使用以下 typedef 重新定义类的问题:
typedef std::map<MyNS::istring, EntityState> Entity;
查看预处理后的输出,可以看到在这个typedef之前有两个class Entity
的前向声明。但是,class Entity
的实际定义不在预处理输出中,而是在与新实体映射相同的命名空间中(虽然不是 MyNS
...)。是导致此错误的前向声明吗?有没有什么方法可以使这在 MSVC 中有效并且由于 Clang 的迂腐而无法工作?
编辑:我手头没有 MSVC,但我整理了一个 sn-p 来演示我遇到的错误类型(我已经简化了定义,以便它们都适合一个小空间) .当我尝试使用 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;
;
【问题讨论】:
有命名空间,里面有实体类的前向声明和std::map上同名的typedef,是吗? 在包含的文件之一中有class Entity
的前向声明,并且在与 typedef 相同的命名空间中存在class Entity
的类定义,但在包含的文件之一中没有(即未显示在预处理输出中)。
为什么不发布Entity
的所有声明(以及声明出现的命名空间)?如果您发布的 sn-p 可以用 clang 编译以产生您所看到的错误(理想情况下在 MSVC 上没有错误),那就更好了。我很难理解问题中的描述。
前向声明与 typedef 在同一个命名空间中?请给他们看。
你的意思是:ideone.com/ganOc?
【参考方案1】:
是的,这是不正确的。永远不应该编译,如果它在 MSVC 上编译 - 可能是编译器的错误。前向声明告诉编译器,TheNS::Entity
将是类,而不是其他任何东西(不是枚举、联合或 typedef)。真的,你的代码是一样的
class Entity;
typedef int Entity;
当然不正确。
n3337 9.1/2
仅由类键标识符组成的声明;要么是名称的重新声明 在当前范围内或作为类名的标识符的前向声明。它介绍了类名 进入当前范围。
那么,在这之后
class Entity;
compiles 知道,Entity
将用作类名。该名称可以重新声明为函数(在同一范围内),在这种情况下,您应该使用class Entity
,当您想使用Entity
类时(或按照cmets 中的说明通过typedef 重新声明Entity
名称)。
7.1.3/6
在给定范围内,不应使用 typedef 说明符重新定义在该范围内声明的任何类型的名称 范围来引用不同的类型。 [ 例子:
class complex /∗ ... ∗/ ; typedef int complex; // error: redifinition
—结束示例]
【讨论】:
typedef struct Entity Entity;
;)以上是关于工作 MSVC 代码的 Clang 中的“使用不同类型的 Typedef 重新定义”错误的主要内容,如果未能解决你的问题,请参考以下文章
gcc、clang 和 msvc 的 C++ 自动矢量化要求
使用 MSVC2015 在 Windows 上进行 clang-tidy