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

bal*_*lki 8 c++ typedef forward-declaration c++11

如果我想使用指向类的指针而我不对其执行任何操作,我们可以转发声明该类.但如果恰好是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();
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 6

typedef不会创建一个类型,它只是为现有类型添加新名称,而您无法转发声明它.我建议你阅读这个不同相关问题的答案,我认为它有助于理解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
Run Code Online (Sandbox Code Playgroud)