2013-02-04 67 views
1

我有一个问题,我们有一些重载函数,但是当它们被第二个参数调用不同类型时,它们总是调用CString版本,而不是适当的过载。C++参数类型转换

带有函数的想法是作为一种基于密钥从缓存中获取和存储值的方法,但问题是编译器选择调用错误的函数。

的函数的定义是:

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 

我们使用Visual Studio 6作为我们的编译器(不,升级不是我希望的那样多),在Windows XP和7上。

+1

这似乎是编译器中的一个严重错误。你有没有尝试过做一个明确的类型转换(如果不需要的话)?此外,哪些重载被调用,有或没有'const CString&'? –

+1

大多数所谓的C++编译器都不完全符合标准,但MSVC 6如此陈旧而且破损,实在不配称为C++编译器。此外,请认识到我们对您的问题的回答可能不适用于VC6,因为它们通常基于标准C++。 – PlasmaHH

回答

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版本的函数,删除了取值为int,longdouble的设置函数的引用,并且还在set函数const中创建了参数。

我认为,VS6编译器只是发现第一个功能过载,即使它不是最合适的,它会执行并使用它。

+0

这在我看来似乎是一个编译器错误。 –

2

我认为这是由CString可以从任何其他类型生成的事实引起的。你可能会发现你需要使CString版本成为一个不同的签名 - 可能会添加另一个整数或其他的数字。

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

例如,

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

现在,编译器不会转换,自动将CStringWrapper。当然,这意味着你必须使用CStringWrapper(mystring)来调用需要使用CString的函数,但是我认为这比不作为CString的evyerthing差。

+0

我认为你对任何可转换为CString的东西都是正确的。我发现移动函数声明的顺序使它首先找到了首选方法,然后在最后使用CString – fwgx