为什么不允许使用typedef的类的前向声明?

时间:2011-06-22 10:09:51

标签: c++ c++11 typedef forward-declaration

如果我想使用指向类的指针而我不对其执行任何操作,我们可以转发声明该类。但如果恰好是typedef,为什么不允许呢? 在下面的例子中,它仅编译我包含注释的代码,但为什么编译器想要在那时知道它?如何转发声明可能是typedef的内容。 c ++ 0x中的这种行为有什么变化吗?

#include <iostream>
using namespace std;
/*
template<class T>
class temp;

typedef temp<int> later;
*/
class later;
void somefunc(later*);
int main()
{
  later* l;
  somefunc(l);
  return 0;
}
//The following is in someother file/compilation unit.
template<class T>
struct temp
{
  public:
    void print()
    {
        T t(5);
        std::cout<< "helloworld: " << t << std::endl;
    }
};
typedef temp<int> later;
void somefunc(later* l)
{
  l = new later();
  l->print();
}

1 个答案:

答案 0 :(得分:6)

typedef不创建类型,只是为现有类型添加新名称,并且您无法转发声明它。我建议您阅读此answer以查看其他相关问题,我认为这有助于理解typedef与用户定义类型声明之间的差异。

另一方面,您可以转发声明实际类型,然后添加typedef。

编辑:扩展您的特定示例:

在声明temp模板后,标识符temp在用户定义的类型标识符空间中可用(与其余符号的标识符空间不同)。 typedef将在全局标识符空间中创建名称later的别名,因此在注释行(取消注释后)之后,用户定义的类型标识符空间将包含temp引用模板,并且驻留在全局标识符空间中的标识符later将引用具体实例化temp<int>。 (多少“标识符”和“空格”!)

另一方面,如果你在第一个未注释的行class later;中转发声明类,那么你正在做的是向用户定义的类型标识符空间添加一个标识符。可以在以下示例中看到差异:

class A;           // Creates A identifier only in user defined types space
typedef int B;     // Creates B identifier in the global identifier space

void A(){}         // Ok: A will refer to void A(); class A will refer to the type
//void B(){}       // Error: B symbol collides with the typedef