我可以在编译器指令中推断出类型的类型吗
Posted
技术标签:
【中文标题】我可以在编译器指令中推断出类型的类型吗【英文标题】:Can I deduce the type of a type in a compiler directive 【发布时间】:2017-06-09 08:17:42 【问题描述】:是否可以像这样创建条件定义:
$if typeof(TNode) = record
type PNode = ^TNode;
$else
type PNode = TNode;
$end
我为什么要这个?
对于特定问题,我在使用 class
和 record
之间交替使用。
出于速度原因,我想使用记录,但为了方便也想使用class
。
出于这个原因,我在两者之间切换。
显然我可以添加一个$define
语句,但如果能够自动执行它会很好。
【问题讨论】:
无论如何我都会使用 $define 方法,因为我想同时切换记录/类定义。这对我来说似乎更简单。 不,据我所知这是不可能的。但我很想被证明是错误的。 这怎么可能奏效呢?PNode^.SomeField
如果它是一个记录指针,则它是有效的,但对于类引用来说是无意义的。当然,这不是一个普遍有效的替代。
@J...,如果是记录指针,您还可以编写 PNode.SomeField
,如果 PNode 是一个类,它也会编译。
您在记录中缺少什么样的便利?你不可能是指继承之类的吧?
【参考方案1】:
虽然我个人推荐一般的 DEFINE 方法,但在记录不是特定大小的情况下,您可能会成功:
$if Sizeof(TNode) <> Sizeof(Pointer)
type PNode = ^TNode;
$else
type PNode = TNode;
$end
好的,我知道这是肮脏的编程,但你一开始就要求这样做。
【讨论】:
请注意,这不是一个通用的解决方案,而是非常专业的。一般来说,如果记录包含的成员的大小发生加起来等于指针的大小,则此操作将失败。例如,如果记录包含一个 32 位的Integer
或一个 64 位的 Int64
。或单个NativeInt
。或任何其他类型的组合,加起来最多为 4 或 8 个字节。【参考方案2】:
如果你控制两个TNode的定义,你可以这样做(不需要在同一个单元,但必须引用相同的常量):
const
NODE_IS_RECORD = False;
type
$if NODE_IS_RECORD
TNode = record
end;
PNode = ^TNode;
$ELSE
TNode = class
end;
PNode = TNode;
$IFEND
如果你只控制 1 个 TNode 声明,你仍然可以这样做:
Unit1
type
TNode = record
end;
PNode = ^TNode;
Unit2
$IF not DECLARED(PNode)
//if you don't use the unit where TNode is a record, then PNode shouldn't be declared.
PNode = TNode;
$ENDIF
如果您不控制任何声明,但它们以不同的单位声明(实际上,我认为这是必需的......)并且您从不使用两者,或者使用两者总是意味着您想要使用 PNode 的特定声明:
$IF DECLARED(UnitContainingTNodeAsRecord)
PNode = ^TNode;
$ELSE
PNode = TNode;
$IFEND
如果您同时使用两个单元,您可能需要在 TNode 前面加上单元名称。 “DECLARED”只确保它被声明,而不是它是范围内“最接近”的。
我认为这涵盖了大多数情况。
【讨论】:
以上是关于我可以在编译器指令中推断出类型的类型吗的主要内容,如果未能解决你的问题,请参考以下文章