1

我有一个问题,我们有许多重载函数,但是当第二个参数使用不同类型调用它们时,它们总是调用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自动转换为 a 。当然,这意味着您必须使用CStringWrapper(mystring)来调用带有 a 的函数CString,但我想这比 evyerthing 是 a 更糟糕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在标题中最后声明了函数的版本,从 set 函数中删除了引用int,longdoublevalues 并且还使 set 函数中的参数为 const。

我认为 VS6 编译器只是找到第一个可以执行的函数重载并使用它,即使它不是最合适的。

于 2013-02-04T11:52:20.343 回答