2017-09-18 51 views
1

我的代碼:E2251曖昧重載調用 'TextToFloat'

function Str2Dbl(const str: string; var v: double): boolean; 
var 
    dp: integer; 
    cstr: string; 
    xv: extended; 
begin 
    if FormatSettings.DecimalSeparator <> '.' then 
    begin 
    dp := pos('.', str); 
    if dp <> 0 then 
    begin 
     cstr := str; 
     cstr[dp] := FormatSettings.DecimalSeparator; 
    end 
    else 
     cstr := str; 
    end 
    else 
    cstr := str; 
    if cstr <> '' then 
    result := TextToFloat(@cstr[1], xv, fvExtended, FormatSettings) 
    else 
    result := false; 
    if result then 
    v := xv; 
end; 

在Delphi 10.2它給出了一個錯誤:

[dcc32 Error] commutil.pas(1005): E2251 Ambiguous overloaded call to 'TextToFloat' 
     System.SysUtils.pas(18332): Related method: function TextToFloat(PWideChar; var; TFloatValue; const TFormatSettings): Boolean; 
     System.SysUtils.pas(18515): Related method: function TextToFloat(PAnsiChar; var; TFloatValue; const TFormatSettings): Boolean; 

我不知道如何解決這個錯誤!

回答

4

錯誤是因爲@cstr[1]的類型爲Pointer,並且重載分辨率不知道需要哪個過載(PAnsiCharPWideChar)。

在任何情況下,使用@cstr[1]通常都是錯誤的,如果cstr爲空,將會因爲運行時錯誤而失敗。改爲使用PChar(cstr)。這也將允許重載解析工作。

我明白你測試cstr是否爲空,但是如果你使用魔法的PChar(...)強制轉換,那麼測試並不是必須的。即使字符串爲空,PChar(...)也會給出以空字符結尾的字符數組的有效指針。

documentation值得在這個問題上諮詢。關鍵語句是:

PChar(S) always returns a pointer to a memory block; if S is empty, a pointer to #0 is returned.

所以,你將能夠取代:

if cstr <> '' then 
    result := TextToFloat(@cstr[1], xv, fvExtended, FormatSettings) 
else 
    result := false; 

這並不反正編譯,有:

result := TextToFloat(PChar(cstr), xv, fvExtended, FormatSettings) 

這確實編譯並避免了if聲明鍋爐板。

除了

我最初的預期,啓用typed address operator{$T+}將使@cstr[1]是一個類型的指針,並有助於重載決議。但是,情況並非如此。這是令人驚訝的,我認爲這個程序編譯:

{$T+} 

var 
    PA: PAnsiChar; 
    PW: PWideChar; 
    s: string; 

begin 
    PA := @s[1]; 
    PW := @s[1]; 
end. 

鏈接的documentation說:

When @ is applied to a variable reference in the {$T+} state, the type of the result is ^T , where T is compatible only with pointers to the type of the variable.

這似乎是由

相矛盾