C++ C++;参数类型转换

C++ C++;参数类型转换,c++,visual-c++,overloading,visual-c++-6,C++,Visual C++,Overloading,Visual C++ 6,我有一个问题,我们有很多重载函数,但是当第二个参数使用不同类型调用它们时,它们总是调用CString版本,而不是适当的重载 函数的思想是基于键从缓存中获取和存储值,但问题是编译器选择调用错误的函数 这些功能的定义如下: bool GetProcessDataItem(LPCTSTR lpszName, CString& strValue, int iIndex = 0, bool bLeveled = false); bool GetProcessDataItem(LPCTSTR lps

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

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

但也许更好的解决方案是为CString提供一个包装器,这样即使在其他适合的情况下,编译器也不会自动选择CString版本

比如说,

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

现在,编译器不会自动转换为
CStringWrapper
。当然,这意味着您必须使用
CStringWrapper(mystring)
来调用使用
CString
的函数,但我想这比使用
CString
的evyerthing更糟糕,毕竟我认为这是一个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
long
double
值,还使设置的函数中的参数为常量


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

这似乎是编译器中的一个严重错误。您是否尝试过执行显式类型转换(如果不需要,则执行事件)?此外,哪种重载被称为“有或没有<代码> const cStand和<代码>?大多数所谓的C++编译器都不是完全标准的一致性,但是MSVC 6太旧,太破了,所以它不应该被称为C++编译器。同样,认识到我们对你的问题的回答可能不适用于VC6,因为它们一般都是基于标准C++的。我认为你对所有可以转换为cSnk的都是正确的。我发现移动函数声明的顺序会使它首先找到首选方法,然后在末尾使用CString,在我看来,这似乎是一个编译器错误。