在前向声明中“使用 typedef-name ... 作为类”

问题描述 投票:0回答:3

我在这里做一些基于策略的设计,我需要输入大量模板类型来缩短名称。
现在的问题是,当我需要使用指向其中一种类型的指针时,我尝试前向声明它,但编译器会抱怨

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++ typedef forward-declaration
3个回答
17
投票

没错。 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)。


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;

2
投票

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

// 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 仍然给出此消息:错误:在“class”之后使用 typedef-name“GarnetNetwork”

我非常感谢您对这个案例的帮助。

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

© www.soinside.com 2019 - 2024. All rights reserved.