因此,存在三个不相关的问题.您提供的报价中的第一个:
struct T * p;
这是非法的,因为T是typedef.
T{};
这在名称空间级别是非法的,但在其他概念上是合法的,例如,作为全局初始化的一部分或在函数内部:
T t = T{};
void f() { T{}; }
这实际上意味着创建类型T的值初始化的临时对象.
T::T(){}
对于默认的构造函数,这将是一个有效的定义,只是您没有声明一个.如果修改S以使用户声明默认构造函数将起作用:
struct S { S(); };
为什么将语言设计为不允许最后两行?
在更新的问题中,这两行是:
struct T* p;
T::T() {}
第二个是合法的,但是您试图定义一个尚未声明为成员的函数,因此它也与原始文本无关.这给我们留下了一个:struct T * p.
动机来自C.用户定义类型和其他名称的标识符似乎位于不同的范围内,当查找试图解析不符合struct或enum的名称时,当尝试解析结构时,它将忽略struct和enums.或枚举它会忽略其他所有内容.以下是有效的C(和C):
struct T {}; // 1
typedef struct S {} T; // 2
struct T t;
在C语言中,查找规则有所变化,您可以使用类型说明符而无需明确限定它,但这是另一回事.另外,可以在C中无法使用的其他上下文中使用类型定义的名称.
一个特殊情况是查找详细的类型说明符,类型定义的名称是否可以在详细的类型说明符中使用?如果是这样,则上面程序的语义将发生变化,并且在C t中类型为T(在1中定义)的地方,在C中变成S(在2中定义).
请注意,在某种程度上这是一个疯狂的猜测,我没有制定规则,也不知道在那里考虑了什么.请注意,C和C在这方面从未真正兼容,一个类似的示例更改了C和C中的语义:
int T;
void f() {
struct T { int data[10]; };
printf("%d
", sizeof(T));
}
该程序将在C语言中打印出比C语言大10倍的数字.但是在少数情况下使用类型而不用类或结构限定类型的能力可能比破坏兼容性更重要…