1

多数のオーバーロードされた関数があるという問題がありますが、それらが 2 番目のパラメーターに異なる型で呼び出されるとCString、適切なオーバーロードではなく、常にバージョンが呼び出されます。

関数の考え方は、キーに基づいてキャッシュから値を取得して格納する方法ですが、問題は、コンパイラが間違った関数を呼び出すことを選択することです。

関数の定義は次のとおりです。

bool GetProcessDataItem(LPCTSTR lpszName, CString& strValue, int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, int& iValue, int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, long& lValue, int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, double& dValue,int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, ATime& tmValue,int iIndex = 0, bool bLeveled = false);

void SetProcessDataItem(LPCTSTR lpszName, const CString& strValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, int& iValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, long& lValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, double& dValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, ATime& tmValue, int iIndex = 0, bool bLeveled = false);

したがって、次のように動作します。

const CString aString = "blah"
SetProcessDataItem("FOO", aString));

CString tmpString;  //to be populated by the Get() call below
GetProcessDataItem("FOO", tmpString);  //tmpString == "blah"

しかし、これはしません:

const double aDouble = 123;
SetProcessDataItem("FOO", aDouble));  //Calls the CString overloaded function (which doesn't convert double -> CString properly, so we get jibberish!)

double tmpDouble = 0;
GetProcessDataItem("FOO", tmpDouble);  //Calls the CString overloaded function and gets the gibberish that was originally passed in above

Windows XP および 7 では、Visual Studio 6 をコンパイラとして使用しています (いいえ、アップグレードは私が望んでいたほどオプションではありません)。

4

2 に答える 2

2

これは、CString が他のどの型からでも生成できることが原因だと思います。CString バージョンを別の署名にする必要があることに気付くかもしれません - おそらく別の整数などを追加してください。

しかし、おそらくより良い解決策は、CString のラッパーを用意することです。これにより、他のバージョンが適切な場合でも、コンパイラが CString バージョンを自動的に選択しないようになります。

例えば、

class CStringWrapper 
{
     CStringWrapper(CString &x) : wrapped(x) {} explicit;
  private:
     CString&  wrapped;
};

現在、コンパイラはCStringWrapper自動的に に変換しません。もちろん、これは をCStringWrapper(mystring)受け取る関数を呼び出すために を使用する必要があることを意味しますが、すべてが .CStringであるよりも悪くないと思いCStringます。

于 2013-02-04T10:46:17.997 に答える
0

解決策は宣言を次のように変更することだったので、これは結局VS6の問題だと思います:

bool GetProcessDataItem(LPCTSTR lpszName, int& iValue, int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, long& lValue, int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, double& dValue,int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, ATime& tmValue,int iIndex = 0, bool bLeveled = false);
bool GetProcessDataItem(LPCTSTR lpszName, CString& strValue, int iIndex = 0, bool bLeveled = false);

void SetProcessDataItem(LPCTSTR lpszName, const int iValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, const long lValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, const double dValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, const ATime& tmValue, int iIndex = 0, bool bLeveled = false);
void SetProcessDataItem(LPCTSTR lpszName, const CString& strValue, int iIndex = 0, bool bLeveled = false);

違いを見ます?

はい、ほとんどありません。CString関数のバージョンをヘッダーの最後に宣言しintlongdouble値を取る set 関数から参照を削除し、set 関数のパラメーターも const にしました。

VS6 コンパイラは、それが最適でなくても、実行する最初の関数のオーバーロードを見つけて使用すると思います。

于 2013-02-04T11:52:20.343 に答える