【问题标题】:"using typedef-name ... as class" on a forward declaration在前向声明中“使用 typedef-name ... 作为类”
【发布时间】:2010-02-14 22:44:38
【问题描述】:

我在这里做一些基于策略的设计,我需要对大量模板类型进行 typedef 以缩短名称。
现在问题来了,当我需要使用指向其中一种类型的指针时,我尝试只前向声明它,但编译器抱怨 test.cpp:8: error: using typedef-name ‘Test1’ after ‘class’
这与大小无关,因为我根本不需要 obj,它只是“.h”文件中的一个指针,我不想将整个模板放入其中。
这是g++:

//Works
class Test{};
class Test;

//Doesn't work
class Test{};
typedef Test Test1;
class Test1;

有什么提示吗?

【问题讨论】:

    标签: c++ compiler-construction typedef forward-declaration


    【解决方案1】:

    没错。 typedef-name 不能在这样的前向声明中使用(这在技术上称为详细类型说明符,如果这样的说明符解析为 typedef-name,则程序格式错误)。

    我不明白为什么您实际上首先需要前向声明。因为如果你已经有了 typedef,为什么不直接使用 typedef 呢?它只是表示那个类。

    编辑:从您的评论来看,您似乎需要一个指定的前向声明标头,这与<iosfwd> 几乎相同。所以,如果你的模板被称为Test_Template_Name_Long,这个标题可能看起来像

    TestFwd.h

    template<typename A, typename B> 
    class Test_Template_Name_Long;
    
    typedef Test_Template_Name_Long<int, bool> Test1;
    

    然后您可以只使用该标头,而不是执行 class Test1,编译器不知道它是什么(并且会认为它是一个新类,独立于任何模板和 typedef)。

    【讨论】:

    • 试图投票给你,因为你打败了我,但我今天没有票了 :(
    • 嗯,问题出在一个 .cpp 文件中,该文件包括这个次要 .h 文件和带有 typedef 的原始文件。我需要前向声明,因为我需要声明一个指向该类的指针,并且希望避免包含模板文件(其中包含 typedef)。那么这样的事情就没有办法解决了吗?
    • 然后你必须在文件中明确地前向声明类和 typedef。请记住,文件之间的 typedef 名称不存在 - 编译器在编译时将它们扩展为它们的 untypedef 名称。如果您稍后只是转发声明 typedef 的名称,那么它将在链接时失败,因为编译后不应该存在这样的名称。
    • 太棒了!感谢您最后的编辑!!我认为这符合我的要求。
    • 我有一个混合 C 和 C++ 的项目。 C 标头有很多 typedef,但我不能只将它们包含在我的 C++ 标头之前,因为它会产生一堆错误。随着项目的发展,事情变得越来越棘手,我想知道避免它们是否是一种好的做法。由于这是在相关的上下文中,任何人都可以给我一个线索吗?
    【解决方案2】:
    typedef Test Test1;
    class Test1;
    

    失败,因为 typedef 语句用作 Test1 类型的声明。

    基本上,当编译器看到 typedef 时,它会记住 Test1 是 Test 的同义词。然后当它看到class Test1; 时,它认为你正在声明一个新类型。但它不能将其视为声明,因为名称 Test1 已被 typedef 使用。

    例如,如果要对 Test1 使用前向声明,则必须将 typedef 放入每个文件中,使用该 typedef 作为前向声明。因此,您可以这样做,而不是 class Test1;

    class Test;
    typedef Test Test1;
    

    【讨论】:

      【解决方案3】:

      出现这种情况的另一种情况是:

      // File: network_fwd.hpp
      #ifndef __NETWORK_FWD_HPP__
      #define __NETWORK_FWD_HPP__
      class Network;
      typedef Network GarnetNetwork;
      #endif // __NETWORK_FWD_HPP__
      
      // File: network.hpp
      #include "network_fwd.hpp"
      
      class GarnetIntLink : public BasicLink
      {
        public:
      
          friend class GarnetNetwork;
      
      };
      

      我必须这样做,因为实际上有一个名为 GarnetNetwork 的类我合并到类 Network 中,并且我想使用该 typedef 将其传播到整个代码的其余部分。 GCC 仍然给出这个消息:error: using typedef-name ‘GarnetNetwork’ after ‘class’.

      非常感谢您对此案的帮助。

      注意:顺便说一下,我在这里发布这个问题是因为我认为这几乎是一回事,并且不会分散社区的注意力。

      【讨论】:

        猜你喜欢
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        • 2010-10-22
        • 2021-10-08
        • 2018-11-02
        • 1970-01-01
        相关资源
        最近更新 更多