C ++参数类型转换

时间:2013-02-04 10:38:04

标签: c++ visual-c++ overloading vc6

我遇到一个问题,我们有多个重载函数,但是当第二个参数调用不同类型时,它们总是调用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作为编译器(不,升级不是我想要的选项)。

2 个答案:

答案 0 :(得分:2)

我认为这是因为CString可以从任何其他类型生成。您可能会发现需要将CString版本设置为不同的签名 - 可能添加另一个整数或其他整数。

但也许更好的解决方案是拥有CString的包装器,这样即使其他人适合,编译器也不会自动选择CString版本。

例如,

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

现在,编译器不会自动转换为CStringWrapper。当然,这意味着您必须使用CStringWrapper(mystring)来调用带有CString的函数,但我认为这比简化为CString要差。

答案 1 :(得分: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值的集合函数的引用,并且还在设置函数const。

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