Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi XE4中的CharInSet编译器警告_Delphi_Delphi 7_Delphi Xe4 - Fatal编程技术网

Delphi XE4中的CharInSet编译器警告

Delphi XE4中的CharInSet编译器警告,delphi,delphi-7,delphi-xe4,Delphi,Delphi 7,Delphi Xe4,我的Delphi7代码中有以下语句 TMyCharSet = set of char; 当我将代码迁移到DelphiXe4时,我在上面一行得到了以下编译器警告 W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit. 我应该如何重新声明TMyCharSet?您会得到警告,因为XE4使用WideChar作为Char类型的变量(而

我的Delphi7代码中有以下语句

TMyCharSet = set of char;
当我将代码迁移到DelphiXe4时,我在上面一行得到了以下编译器警告

W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

我应该如何重新声明TMyCharSet?

您会得到警告,因为XE4使用WideChar作为Char类型的变量(而WideString作为String),所以Char现在需要2个字节而不是1个字节。现在可以将unicode字符保存在String/Char中,但出于同样的原因,无法再使用Char集(在Delphi中,它是固定大小的,32字节位映射,最多可以保存256个项目)

如果仅使用范围为0..127的字符(仅使用拉丁/常规符号),则可以替换Char->AnsiChar(但当从Char分配它时,您将看到另一个警告,您必须使用显式类型转换来抑制它)

如果您需要国家/unicode符号,则Delphi中没有“即用”结构,但您可以为此使用Tdictionary:

type
  TEmptyRecord = record end;

  TSet<T> = class(TDictionary<T,TEmptyRecord>)
  public
    procedure Add(Value: T); reintroduce; inline;
    procedure AddOrSetValue(Value: T); reintroduce; inline;
    function Contains(Value: T):Boolean; reintroduce; inline;
  end;

procedure TSet<T>.Add(Value: T);
var Dummy: TEmptyRecord;
begin
  inherited AddOrSetValue(Value, Dummy);
end;

procedure TSet<T>.AddOrSetValue(Value: T);
var Dummy: TEmptyRecord;
begin
  inherited AddOrSetValue(Value, Dummy);
end;

function TSet<T>.Contains(Value: T): Boolean;
begin
  result := inherited ContainsKey(Value);
end;
类型
试探记录=记录结束;
TSet=类别(t字典)
公众的
程序增加(值:T);重新引入;内联;
程序AddOrSetValue(值:T);重新引入;内联;
函数包含(值:T):布尔值;重新引入;内联;
结束;
程序TSet.Add(值:T);
虚拟变量:试探记录;
开始
继承的AddOrSetValue(值,虚拟);
结束;
程序TSet.AddOrSetValue(值:T);
虚拟变量:试探记录;
开始
继承的AddOrSetValue(值,虚拟);
结束;
函数TSet.Contains(值:T):布尔值;
开始
结果:=继承的ContainsKey(值);
结束;
当然,您必须像初始化任何其他常规类一样初始化。 但它仍然非常有效(当然没有“set of”那么快,因为“set”总是受256个项目的最大大小限制,但高度优化)


或者,您可以为unicode字符创建自己的set类作为位映射,保留所有位需要8kb的内存,速度几乎与“set of”一样快。

一个集合不能包含大于一个字节的项。由于UniCode Delphi中的
Char
是两个字节大小的
WideChar
,因此集合类型是不合适的容器

下面是一个基于记录的泛型集合类型示例,
TSet
。这意味着您不必考虑创建和销毁这种类型的变量。将此类型用作简单类型的容器。我试着模仿大多数集合类型的行为。 项目的加减可以使用+和-运算符完成。在操作符中添加了

注意:记录将数据保存在动态数组中。将一个变量分配给另一个变量将使两个变量使用相同的动态数组。内置的写时拷贝(COW)保护将防止一个变量的更改反映在另一个变量上

unit GenericSet;

interface

Uses
  System.Generics.Defaults;

Type
  TSet<T> = record
    class operator Add(const aSet: TSet<T>; aValue: T) : TSet<T>; overload;
    class operator Add(const aSet: TSet<T>; const aSetOfT: TArray<T>) : TSet<T>; overload;
    class operator Add(const aSet1: TSet<T>; const aSet2: TSet<T>) : TSet<T>; overload;
    class operator Subtract(const aSet: TSet<T>; aValue: T): TSet<T>; overload;
    class operator Subtract(const aSet: TSet<T>; const aSetOfT: TArray<T>) : TSet<T>; overload;
    class operator Subtract(const aSet1: TSet<T>; const aSet2: TSet<T>) : TSet<T>; overload;
    class operator In(aValue: T; const aSet: TSet<T>): Boolean; overload;
    class operator In(const aSetOf: TArray<T>; const aSet: TSet<T>): Boolean; overload;
    class operator In(const aSet1: TSet<T>; const aSet2: TSet<T>): Boolean; overload;
  private
    FSetArray : TArray<T>;
    function GetEmpty: Boolean;
  public
    procedure Add(aValue: T);
    procedure AddSet(const setOfT: array of T); overload;
    procedure AddSet(const aSet: TSet<T>); overload;
    procedure Remove(aValue: T);
    procedure RemoveSet(const setOfT: array of T); overload;
    procedure RemoveSet(const aSet : TSet<T>); overload;
    function Contains(aValue: T): Boolean; overload;
    function Contains(const aSetOfT: array of T): Boolean; overload;
    function Contains(const aSet : TSet<T>): Boolean; overload;
    procedure Clear;
    property Empty: Boolean read GetEmpty;
  end;

implementation

procedure TSet<T>.Add(aValue: T);
begin
  if not Contains(aValue) then begin
    SetLength(FSetArray,Length(FSetArray)+1);
    FSetArray[Length(FSetArray)-1] := aValue;
  end;
end;

class operator TSet<T>.Add(const aSet: TSet<T>; aValue: T): TSet<T>;
begin
  Result.AddSet(aSet.FSetArray);
  Result.Add(aValue);
end;

class operator TSet<T>.Add(const aSet: TSet<T>; const aSetOfT: TArray<T>): TSet<T>;
begin
  Result.AddSet(aSet.FSetArray);
  Result.AddSet(aSetOfT);
end;

class operator TSet<T>.Add(const aSet1, aSet2: TSet<T>): TSet<T>;
begin
  Result.AddSet(aSet1.FSetArray);
  Result.AddSet(aSet2.FSetArray);
end;

procedure TSet<T>.AddSet(const setOfT: array of T);
var
  i : Integer;
begin
  for i := 0 to High(setOfT) do
    Self.Add(setOfT[i]);
end;

procedure TSet<T>.AddSet(const aSet: TSet<T>);
begin
  AddSet(aSet.FSetArray);
end;

procedure TSet<T>.RemoveSet(const setOfT: array of T);
var
  i : Integer;
begin
  for i := 0 to High(setOfT) do
    Self.Remove(setOfT[i]);
end;

procedure TSet<T>.RemoveSet(const aSet: TSet<T>);
begin
  RemoveSet(aSet.FSetArray);
end;

class operator TSet<T>.Subtract(const aSet1, aSet2: TSet<T>): TSet<T>;
begin
  Result.AddSet(aSet1.FSetArray);
  Result.RemoveSet(aSet2.FSetArray);
end;

class operator TSet<T>.Subtract(const aSet: TSet<T>;
  const aSetOfT: TArray<T>): TSet<T>;
begin
  Result.AddSet(aSet.FSetArray);
  Result.RemoveSet(aSetOfT);
end;

class operator TSet<T>.Subtract(const aSet: TSet<T>; aValue: T): TSet<T>;
begin
  Result.AddSet(aSet.FSetArray);
  Result.RemoveSet(aValue);
end;

class operator TSet<T>.In(aValue: T; const aSet: TSet<T>): Boolean;
begin
  Result := aSet.Contains(aValue);
end;

class operator TSet<T>.In(const aSetOf: TArray<T>; const aSet: TSet<T>): Boolean;
begin
  Result := aSet.Contains(aSetOf);
end;

class operator TSet<T>.In(const aSet1: TSet<T>; const aSet2: TSet<T>): Boolean;
begin
  Result := aSet2.Contains(aSet1.FSetArray);
end;

function TSet<T>.Contains(aValue: T): Boolean;
var
  i : Integer;
  c : IEqualityComparer<T>;
begin
  c := TEqualityComparer<T>.Default;
  Result := false;
  for i := 0 to Length(FSetArray)-1 do
    if c.Equals(FSetArray[i],aValue) then
      Exit(True);
end;

function TSet<T>.GetEmpty: Boolean;
begin
  Result := (Length(FSetArray) = 0);
end;

procedure TSet<T>.Clear;
begin
  SetLength(FSetArray,0);
end;

function TSet<T>.Contains(const aSetOfT: array of T): Boolean;
var
  i : Integer;
begin
  Result := High(aSetOfT) >= 0;
  for i := 0 to High(aSetOfT) do
  begin
    Result := Contains(ASetOfT[i]);
    if not Result then
      Exit(false);
  end;
end;

function TSet<T>.Contains(const aSet: TSet<T>): Boolean;
begin
  Result := Contains(aSet.FSetArray);
end;

procedure TSet<T>.Remove(aValue: T);
var
  i : Integer;
  c : IEqualityComparer<T>;
begin
  c := TEqualityComparer<T>.Default;
  for i := 0 to Length(FSetArray)-1 do
  begin
    if c.Equals(FSetArray[i],aValue) then
    begin
      SetLength(FSetArray,Length(FSetArray)); // Ensure unique dyn array
      if (i < Length(FSetArray)-1) then
        FSetArray[i] := FSetArray[Length(FSetArray)-1]; // Move last element
      SetLength(FSetArray,Length(FSetArray)-1);
      Break;
    end;
  end;
end;

end.
unitgenericset;
接口
使用
System.Generics.Defaults;
类型
TSet=记录
类运算符Add(const-aSet:TSet;aValue:T):TSet;超载;
类操作符Add(const-aSet:TSet;const-aSetOfT:TArray):TSet;超载;
类运算符Add(const-aSet1:TSet;const-aSet2:TSet):TSet;超载;
类运算符减法(const-aSet:TSet;aValue:T):TSet;超载;
类运算符减法(const-aSet:TSet;const-aSetOfT:TArray):TSet;超载;
类运算符减法(常量aSet1:TSet;常量aSet2:TSet):TSet;超载;
(aValue:T;const-aSet:TSet)中的类运算符:布尔;超载;
中的类运算符(const-aSetOf:TArray;const-aSet:TSet):布尔;超载;
中的类运算符(const-aSet1:TSet;const-aSet2:TSet):布尔;超载;
私有的
Fsetaray:焦油;
函数GetEmpty:Boolean;
公众的
程序添加(aValue:T);
过程AddSet(const setOfT:T的数组);超载;
程序地址集(const-aSet:TSet);超载;
程序删除(aValue:T);
过程RemoveSet(const setOfT:T的数组);超载;
程序删除集(const-aSet:TSet);超载;
函数包含(aValue:T):布尔值;超载;
函数包含(const aSetOfT:T的数组):布尔值;超载;
函数包含(const-aSet:TSet):布尔值;超载;
程序清晰;
属性为空:布尔读取GetEmpty;
结束;
实施
程序TSet.Add(aValue:T);
开始
如果不包含(aValue),则开始
设置长度(FSetArray,长度(FSetArray)+1);
FSetArray[长度(FSetArray)-1]:=aValue;
结束;
结束;
类运算符TSet.Add(const-aSet:TSet;aValue:T):TSet;
开始
Result.AddSet(aSet.FSetArray);
结果。添加(aValue);
结束;
类运算符TSet.Add(const-aSet:TSet;const-aSetOfT:TArray):TSet;
开始
Result.AddSet(aSet.FSetArray);
结果:AddSet(aSetOfT);
结束;
类运算符TSet.Add(const aSet1,aSet2:TSet):TSet;
开始
Result.AddSet(aSet1.fsetaray);
Result.AddSet(aSet2.fsetaray);
结束;
程序TSet.AddSet(const setOfT:T的数组);
变量
i:整数;
开始
对于i:=0到高(setOfT)do
Self.Add(setOfT[i]);
结束;
程序TSet.AddSet(const-aSet:TSet);
开始
AddSet(aSet.FSetArray);
结束;
程序TSet.RemoveSet(const setOfT:T的数组);
变量
i:整数;
开始
对于i:=0到高(setOfT)do
自我移除(setOfT[i]);
结束;
程序TSet.RemoveSet(常数集:TSet);
开始
移除集合(aSet.fsetaray);
结束;
类运算符TSet.Subtract(常量aSet1,aSet2:TSet):TSet;
开始
Result.AddSet(aSet1.fsetaray);
结果:RemoveSet(aSet2.FSetArray);
结束;
类运算符TSet.Subtract(const-aSet:TSet;
常数aSetOfT:TArray):TSet;
开始
Result.AddSet(aSet.FSetArray);
结果:移除集合(aSetOfT);
结束;
类运算符TSet.Subtract(const-aSet:TSet;aValue:T):TSet;
开始
Result.AddSet(aSet.FSetArray);
结果:移除设置(aValue);
结束;
类运算符TSet.In(aValue:T;const-aSet:TSet):布尔;
开始
结果:=aSet.Contains(aValue);
结束;
类运算符TSet.In(const-aSetOf:TArray;const-aSet:TSet):布尔;
开始
结果:=aSet.Contains(aSetOf);
结束;
类运算符TSet.In(常量aSet1:TSet;常量aS
program ProjectGenericSet;
{$APPTYPE CONSOLE}    
uses
  GenericSet in 'GenericSet.pas';

var
 mySet,mySet1 : TSet<Char>;
begin
  mySet.AddSet(['A','B','C']);
  WriteLn(mySet.Contains('C'));
  WriteLn(mySet.Contains('D'));  // False
  mySet := mySet + 'D';
  WriteLn(mySet.Contains('D'));
  WriteLn('D' in mySet);
  mySet := mySet - 'D';
  WriteLn(mySet.Contains('D'));  // False
  mySet := mySet + TArray<Char>.Create('D','E');
  WriteLn(mySet.Contains('D'));
  WriteLn(mySet.Contains(['A','D']));
  mySet1 := mySet;
  // Testing COW
  mySet1.Remove('A');
  WriteLn(mySet.Contains('A'));
  mySet1:= mySet1 + mySet;
  WriteLn(mySet1.Contains('A'));
  mySet := mySet1;
  mySet1.Clear;
  WriteLn(mySet.Contains('A'));
  ReadLn;
end.
if not (CharInSet(Key,['0'..'9',#8]) then key := #0;