为什么我不能使用typedef完成类型?

时间:2015-05-10 19:32:35

标签: c++ language-lawyer

鉴于翻译单元A中的类型不完整:

struct Incomplete;

Incomplete* create_incomplete();
void destroy_incomplete(Incomplete*);

为什么我不能在另一个翻译单元中使用typedef

例如在翻译单元B中:

struct Unrelated
{
    int x;
    int y;
};

typedef Unrelated Incomplete;

Incomplete* create_incomplete()
{
    return new Incomplete();
}

void destroy_incomplete(Incomplete* arg)
{
    delete arg;
}

2 个答案:

答案 0 :(得分:4)

Incomplete是一种类型,由您的声明引入,您不能使用相同名称的typedef,引用另一种类型。

您的struct Incomplete;是一个前向类声明,它将一个类名插入到全局范围中(并引入了一个新的但不完整的类型)。

<强>§9/ 2

  

在看到类名后立即将类名插入到作用域中。

<强>第9.1节/ 2

  

仅由类密钥标识符组成的声明;是对当前作用域中名称的重新声明,或者是作为类名称的标识符的前向声明。

为了在需要完整类型的地方使用该名称,必须对其进行定义。

<强>§3.2/ 4

  

如果以需要类类型完整的方式使用类,则翻译单元中只需要一个类的定义。

使用类说明符定义类。

<强>§9/ 2

  

一个类被认为是在看到它的类说明符的右括号之后定义的,即使它的成员函数一般尚未定义。

您的typedef是一个声明,并没有定义该类。

<强>§7.1.3/ 1

  

包含decl-specifier typedef的声明声明了以后可用于命名基本(3.9.1)或复合(3.9.2)类型的标识符。

<强>§3.1/ 2

  

声明是一个定义,除非它是一个typedef声明[...]。

而同一范围/声明区域中的声明需要引用同一实体。

<强>§3.3.1/ 4

  

在单个声明性区域中给出一组声明,每个声明都指定相同的非限定名称

     
      
  • 他们都应该引用同一个实体,或者全部引用功能和功能模板; [...]
  •   

您的typedef声明Incomplete引用Unrelatedstruct Incomplete;声明类型Incomplete

<强>§7.1.3/ 6

  

在给定范围内,typedef说明符不得用于重新定义在该范围内声明的任何类型的名称以引用其他类型。

C ++ 11

答案 1 :(得分:2)

您无法完成在不同翻译单元中声明的内容。您#include是第二个文件中的第一个文件,在这种情况下,您可以在一个翻译单元中执行所有操作,或者,如果您没有#include,则只需typedef单元A中没有不完整的类型,单元A中没有不完整的类型(因为你没有必要完成)。

您无法在一个单元中完成一个typedef的课程,因为:

  

3.9.5。已声明但未定义的类或未知数组   大小或不完整的元素类型,是一个未完全定义的对象   类型。不完整定义的对象类型和void类型   不完整类型

  

3.9.2。声明是定义,除非&lt; ...&gt;它是typedef声明,&lt; ...&gt;。

N3337;我强调了一些重点。)

因此,您无法使用typedef完成类类型,因为类类型只能通过定义完成,而typedef声明不是定义。