工作 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 重新定义”错误的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式在 MSVC 和 Clang 上设置堆栈指针

gcc、clang 和 msvc 的 C++ 自动矢量化要求

Clang如何处理MSVC的编译参数

使用 MSVC2015 在 Windows 上进行 clang-tidy

GCC 和 clang 上的 MSVC /Zp 替代方案是啥?

MSVC++14 上的 C++11 中的不可能的快速委托