为什么编译器找不到我函数的重载版本?
Why can't the compiler find the overloaded version of my function?
没有 Get
重载(仅使用 Get
的第一个定义)否则编译正常:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes;
type
TxALNameValuePair = record
Name: ansistring;
Value: ansistring;
constructor Create(const AName, AValue: ansistring);
end;
TxALNameValueArray = TArray<TxALNameValuePair>;
TxALHTTPClient = class(TObject)
private
protected
public
Function Get(const aUrl:AnsiString;
const ARequestHeaderValues: TxALNameValueArray = nil): AnsiString; overload;
Function Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TArray<TxALNameValuePair> = nil): AnsiString; overload;
end;
constructor TxALNameValuePair.Create(const AName, AValue: ansiString);
begin
Name := AName;
Value := AValue;
end;
function TxALHTTPClient.Get(const aUrl: AnsiString;
const ARequestHeaderValues: TxALNameValueArray): AnsiString;
begin
end;
Function TxALHTTPClient.Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
Const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TArray<TxALNameValuePair> = nil): AnsiString;
begin
end;
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com', [TxALNameValuePair.Create('Accept-Encoding', 'gzip')]);
ReadLn;
end.
但是当 Get
过载时它会产生
[dcc64 Error] E2250 There is no overloaded
version of 'Get' that can be called with these arguments
为什么编译器无法解析此重载?
这里的问题是您正在使用的动态数组构造函数正在生成类型为 array of TxALNameValuePair
的对象,但是您所有的重载都要求类型为 TxALNameValueArray
,而且似乎对于 T => TAxTxALNameValuePair
.
,编译器没有在 array of TxALNameValuePair
==> TArray<T>
之间建立连接
当重载没有引起歧义时,数组可以隐式转换为正确的类型,否则似乎您必须以某种方式提供该类型信息。最简单(也可能是最清晰)的方法就是使用变量。
var
aHttpCLient: TxALHTTPClient;
nvpArray : TxALNameValueArray;
begin
aHttpClient := TxALHTTPClient.Create;
nvpArray := [TxALNameValuePair.Create('Accept-Encoding', 'gzip')];
aHttpCLient.get('http://www.toto.com', nvpArray);
ReadLn;
end.
您还可以使用类型化动态数组构造函数就地构造数组:
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com',
TxALNameValueArray.Create(
TxALNameValuePair.Create('Accept-Encoding', 'gzip')
));
ReadLn;
end.
否则,除非对自己的 name-value 对记录类型有特殊需要,否则您可以只使用 System.Net.URLClient
中提供的那种:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes, System.Net.URLClient;
type
TxALHTTPClient = class(TObject)
private
protected
public
Function Get(const aUrl:AnsiString;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString; overload;
Function Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString; overload;
end;
function TxALHTTPClient.Get(const aUrl: AnsiString;
const ARequestHeaderValues: TNameValueArray): AnsiString;
begin
end;
Function TxALHTTPClient.Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
Const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString;
begin
end;
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com', [TNameValuePair.Create('Accept-Encoding', 'gzip')]);
ReadLn;
end.
我猜这只是因为编译器的魔法,它是一个系统定义的类型。
再往下走,您同样可以使用 TNetHeaders
而不是 TNameValueArray
,前者只是该类型的别名。您还可以创建自己的别名,例如
TxALNameValueArray = TNetHeaders;
如果你真的想要。
深入挖掘,我们可以生成一个显示问题的最小示例:
program Project1;
{$APPTYPE CONSOLE}
type
TDblArray = TArray<double>;
procedure A(i : integer; da : TDblArray); overload;
begin
end;
procedure A(s : string; da : TDblArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
编译时不会出现同样的错误。
这确实有效,但是:
program Project1;
{$APPTYPE CONSOLE}
type
TDblArray = array of double;
procedure A(i : integer; da : TDblArray); overload;
begin
end;
procedure A(s : string; da : TDblArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
就像这样:
program Project1;
{$APPTYPE CONSOLE}
uses Types;
procedure A(i : integer; da : TDoubleDynArray); overload;
begin
end;
procedure A(s : string; da : TDoubleDynArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
也许我们想称之为编译器错误?我不确定。正常的类型解析向前工作,但对于重载解析,它必须向后工作……在一般情况下,这可能是一个停止的问题情况。如果您对此有强烈的感觉,可以提交 QP。
没有 Get
重载(仅使用 Get
的第一个定义)否则编译正常:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes;
type
TxALNameValuePair = record
Name: ansistring;
Value: ansistring;
constructor Create(const AName, AValue: ansistring);
end;
TxALNameValueArray = TArray<TxALNameValuePair>;
TxALHTTPClient = class(TObject)
private
protected
public
Function Get(const aUrl:AnsiString;
const ARequestHeaderValues: TxALNameValueArray = nil): AnsiString; overload;
Function Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TArray<TxALNameValuePair> = nil): AnsiString; overload;
end;
constructor TxALNameValuePair.Create(const AName, AValue: ansiString);
begin
Name := AName;
Value := AValue;
end;
function TxALHTTPClient.Get(const aUrl: AnsiString;
const ARequestHeaderValues: TxALNameValueArray): AnsiString;
begin
end;
Function TxALHTTPClient.Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
Const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TArray<TxALNameValuePair> = nil): AnsiString;
begin
end;
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com', [TxALNameValuePair.Create('Accept-Encoding', 'gzip')]);
ReadLn;
end.
但是当 Get
过载时它会产生
[dcc64 Error] E2250 There is no overloaded version of 'Get' that can be called with these arguments
为什么编译器无法解析此重载?
这里的问题是您正在使用的动态数组构造函数正在生成类型为 array of TxALNameValuePair
的对象,但是您所有的重载都要求类型为 TxALNameValueArray
,而且似乎对于 T => TAxTxALNameValuePair
.
array of TxALNameValuePair
==> TArray<T>
之间建立连接
当重载没有引起歧义时,数组可以隐式转换为正确的类型,否则似乎您必须以某种方式提供该类型信息。最简单(也可能是最清晰)的方法就是使用变量。
var
aHttpCLient: TxALHTTPClient;
nvpArray : TxALNameValueArray;
begin
aHttpClient := TxALHTTPClient.Create;
nvpArray := [TxALNameValuePair.Create('Accept-Encoding', 'gzip')];
aHttpCLient.get('http://www.toto.com', nvpArray);
ReadLn;
end.
您还可以使用类型化动态数组构造函数就地构造数组:
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com',
TxALNameValueArray.Create(
TxALNameValuePair.Create('Accept-Encoding', 'gzip')
));
ReadLn;
end.
否则,除非对自己的 name-value 对记录类型有特殊需要,否则您可以只使用 System.Net.URLClient
中提供的那种:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes, System.Net.URLClient;
type
TxALHTTPClient = class(TObject)
private
protected
public
Function Get(const aUrl:AnsiString;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString; overload;
Function Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString; overload;
end;
function TxALHTTPClient.Get(const aUrl: AnsiString;
const ARequestHeaderValues: TNameValueArray): AnsiString;
begin
end;
Function TxALHTTPClient.Get(const aUrl:AnsiString;
const aRequestFields: TStrings;
Const aEncodeRequestFields: Boolean=True;
const ARequestHeaderValues: TNameValueArray = nil): AnsiString;
begin
end;
var
aHttpCLient: TxALHTTPClient;
begin
aHttpClient := TxALHTTPClient.Create;
aHttpCLient.get('http://www.toto.com', [TNameValuePair.Create('Accept-Encoding', 'gzip')]);
ReadLn;
end.
我猜这只是因为编译器的魔法,它是一个系统定义的类型。
再往下走,您同样可以使用 TNetHeaders
而不是 TNameValueArray
,前者只是该类型的别名。您还可以创建自己的别名,例如
TxALNameValueArray = TNetHeaders;
如果你真的想要。
深入挖掘,我们可以生成一个显示问题的最小示例:
program Project1;
{$APPTYPE CONSOLE}
type
TDblArray = TArray<double>;
procedure A(i : integer; da : TDblArray); overload;
begin
end;
procedure A(s : string; da : TDblArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
编译时不会出现同样的错误。
这确实有效,但是:
program Project1;
{$APPTYPE CONSOLE}
type
TDblArray = array of double;
procedure A(i : integer; da : TDblArray); overload;
begin
end;
procedure A(s : string; da : TDblArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
就像这样:
program Project1;
{$APPTYPE CONSOLE}
uses Types;
procedure A(i : integer; da : TDoubleDynArray); overload;
begin
end;
procedure A(s : string; da : TDoubleDynArray); overload;
begin
end;
begin
A(1, [1.0]);
end.
也许我们想称之为编译器错误?我不确定。正常的类型解析向前工作,但对于重载解析,它必须向后工作……在一般情况下,这可能是一个停止的问题情况。如果您对此有强烈的感觉,可以提交 QP。