为什么我不能转发声明类型定义?
Why can't I forward declare typedefs?
namespace O
{
class A{};
class A; // ok
typedef A K; // ok
struct A; // ok(C++11): A is a class but for references and pointer it have the same meaning
class K; // (1) error: K is a typedef (of a class...)
}
namespace U
{
typedef O::A A;
class A; // (2) error: A is a typedef (of a class...)
}
标准C++不允许编译这些情况(1和2)的原因是什么?
你很困惑,或者你的例子没有显示你在问什么。在你的示例代码中,你不是试图"向前声明一个typedef"(例如事情是不可能的或有用的,见下文),你试图将现有的typedef-name(即一种类型的别名)重新声明为完全不同的类型。
你已经说过K
是A
的typedef,然后你说它是一个类K
。下定决心。 它不能既class A
又class K
. (1) 和 (2) 都因同样的原因而失败。
浏览示例的以下行:
class A; // ok
typedef A K; // ok
到目前为止。
struct A; // ok(C++11): A is a class but for references and pointer it have the same meaning
我不知道你为什么在这里说"C++11",这在 C++03 中也可以。类和结构在C++是同一种东西。它们既是"对象类型",也是"类类型"。对于前向声明,类键(即 struct
或class
)是可以互换的。
class K; // (1) error: K is a typedef (of a class...)
K
已被声明为类 A
的 typedef,则该名称不能重用于声明同一范围内的新类型。
[旁白:C 确实允许以下内容,因为结构名称和 typedef 名称位于不同的命名空间中:
struct A { };
typedef struct A K; // N.B. need "struct A" not just "A"
struct K { };
但是现在有两种不同的类型,称为struct K
和K
,它们是不相关的。这样做会令人困惑和愚蠢。
但从你的评论来看,也许这不是你真正想做的。
根据您的评论,也许您的破碎示例具有误导性,您真正想做的是:
typedef class A K; // forward declare A as class and declare K as typedef for it
这将为尚未定义的类型声明一个 typedef。
向前声明 typedef 是没有用的,你不能用它做任何事情,因为你不知道它是 typedef 的哪种类型,而且如果不了解类型,你几乎无法在C++中做任何事情。在不知道它是对象类型、引用类型还是函数类型的情况下,您实际上所能做的就是为它声明另一个 typedef!
考虑:
typedef K; // declares K to be a typedef
K* f(); // function returning pointer to K
void g(K*); // function taking pointer to K
我想你是说你希望这是有效的,那么你希望这能奏效吗?
K* k = f();
g(k);
这应该有效,对吧?您不需要知道K
的类型,因为您只传递指向它的指针,对吧? 错。如果您稍后像这样定义K
会怎样:
typedef int& K;
现在f
具有无效的签名int&* f()
。 你必须知道typedef是typedef的用途,所以它的声明必须说明它是什么,而不仅仅是向前声明为一个名称。
让我解决第一个错误:
- 创建类 A
- :此时,名称"A"被分配给该类;此作用域中没有其他实体可以称为"A"。
- 然后你键入 def,以便 K 现在引用 A,因此此作用域中的其他实体都不能称为"K"。
- 然后你尝试转发声明 K.转发声明本身很好,但名称 K 已经被你的 typedef 采用。在这一点上,它与A关系不大。您也无法转发声明 A,这两个名称都已被您以前的使用所采用。
你到底想做什么?
>我在 C++2003 标准中找不到这个东西。但是 C 编译器不允许这样的事情,因为 typedef 构造定义了新类型,然后你尝试通过类 A 再次定义新类型。
原则上允许在两个用例中使用"前向声明类":
- 类型定义名称
- 指向结构的指针
这两个操作都不需要有关 sizeof 类型和内存布局的信息。同样在上面的列表中没有"引用",因为 C 语言中没有引用。
另见:(Samuel P. Harbison, Guy L.Steele] C A Reference,第151页。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 列表参数的类型定义
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 关于 C++ 中的函数类型定义
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 将使用/类型定义限制为类范围
- 模板类型定义?
- C++:模板类的类型定义
- 如何对命名空间限定类型进行类型定义?
- 此递归模板类型定义是否有效C++?
- 具有调整对齐方式的类型定义
- C++从抽象类型定义类成员
- 用于C++代码的 API 监视器类型定义 (XML)
- 如何将result_of与函数类型定义一起使用
- 在C++的适当类型定义位置
- 如何根据模板类型定义浮点常量?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 参数化类的别名(或类型定义)内部类
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?