Pregunta

I have an issue where we have a number of overloaded functions, but when they are called with different types for the second parameter they always call into the CString version and not the appropriate overload.

The idea with the functions is as a way of getting and storing values from a cache based on a key, but the issue is that the compiler chooses to call the wrong functions.

The definitions of the functions are:

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);

So the following works OK:

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

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

But this doesn't:

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

We are using Visual Studio 6 as our compiler (no, upgrading is NOT an option as much as I wish it were) on Windows XP and 7 .

¿Fue útil?

Solución 2

Well I think this is a VS6 issue after all as the solution was to change the declarations to this:

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);

See the difference?

Yeah there barely is one. I declared the CString version of the functions last in the header, removed references from the set functions that took int, long and double values and also made the params in the set function const.

I think the VS6 compiler just finds the first function overload that will do and uses that, even if it's not the best fit.

Otros consejos

I think this is caused by the fact that CString can be produced from any other type. You may find that you need to make the CString version a different signature - perhaps add another integer or some such.

But perhaps a better solution is to have a wrapper for CString, such that the compiler doesn't automatically choose the CString version even when others are suitable.

For example,

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

Now, the compiler won't convert to a CStringWrapper automatically. Of course, it means you have to use CStringWrapper(mystring) to call the functions that take a CString, but I guess that's less bad than evyerthing being a CString.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top