德尔福“在”集合上的运算符重载
在 Delphi XE2 中,我尝试重载记录上的 in
运算符,以允许我检查记录表示的值是否是集合的一部分。我的代码如下所示:
type
MyEnum = (value1, value2, value3);
MySet = set of MyEnum;
MyRecord = record
Value: MyEnum;
class operator In(const A: MyRecord; B: MySet): Boolean;
end;
class operator MyRecord.In(const A: MyRecord; B: MySet): Boolean;
begin
Result := A.Value in B;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
R: MyRecord;
S: MySet;
begin
R.Value := value1;
S := [value1, value2];
Button1.Caption := BoolToStr(R in S);
end;
代码无法编译。对于语句R in S
,编译器会说:不兼容的类型MyRecord
和MyEnum
。
如何重载 MyRecord
上的 In
运算符,以便上述代码中的 R in S
计算结果为 True
?
In Delphi XE2, I'm trying to overload the in
operator on a record to allow me to check whether the value represented by the record is part of a set. My code looks like this:
type
MyEnum = (value1, value2, value3);
MySet = set of MyEnum;
MyRecord = record
Value: MyEnum;
class operator In(const A: MyRecord; B: MySet): Boolean;
end;
class operator MyRecord.In(const A: MyRecord; B: MySet): Boolean;
begin
Result := A.Value in B;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
R: MyRecord;
S: MySet;
begin
R.Value := value1;
S := [value1, value2];
Button1.Caption := BoolToStr(R in S);
end;
The code fails to compile. For the statement R in S
the compiler says: Incompatible types MyRecord
and MyEnum
.
How can I overload the In
operator on MyRecord
so that R in S
will evaluate to True
in the above code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了使 in 运算符起作用,正确的操作数必须是记录类型,因为它是集合运算符而不是二元运算符。在你的情况下,它是左操作数。
因此,以下内容将起作用:
For the in operator to work the right operand must be of the record type since it's a set operator and not a binary operator. In your case it is the left operand.
So the following will work:
好吧,您几乎可以做到这一点,但您可能不想这样做。 AFAIK,类运算符仅适用于它们定义的类(或记录),因此代码中的 R 和 S 都必须是 TMyRecord。通过一些不明智地使用隐式转换,我们得到以下结果:
以下内容现在将编译,甚至可以工作:
我相信我们都会同意,它比“BoolToStr(R.Value in S)”优雅得多。
然而,以下内容也将编译,但给出错误的结果:
因此,正如 Dorin 评论的那样,最好只使用沉闷、古板的“BoolToStr(R.Value in S)”。当然,除非您按行代码付费。以及修复错误的奖励。
Well, you can almost do this, but you may not want to. AFAIK, class operators only work on the class (or record) they are defined within, so both R and S in your code have to be TMyRecord. With some injudicious use of implicit casting, we get the following:
The following will now complile, and even work:
Which, I'm sure we will all agree, is much more elegant than 'BoolToStr(R.Value in S)'.
However the following will also compile, but give the wrong result:
So, as Dorin commented, better to just have dull, staid old 'BoolToStr(R.Value in S)'. Unless of course you are being paid per line of code. And a bonus for bug-fixing.