У меня есть проблема, когда у нас есть несколько перегруженных функций, но когда они вызываются с разными типами для второго параметра, они всегда вызывают в 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
Мы используем Visual Studio 6 в качестве нашего компилятора (нет, обновление, как я бы этого не хотел) в Windows XP и 7.
Я думаю, что это связано с тем, что CString может быть произведен из любого другого типа. Вы можете обнаружить, что вам нужно сделать версию CString другой подписью — возможно, добавить еще одно целое число или что-то подобное.
Но, возможно, лучшим решением будет использование обертки для CString, чтобы компилятор не выбирал автоматически версию CString, даже когда другие подходят.
Например,
class CStringWrapper
{
CStringWrapper(CString &x) : wrapped(x) {} explicit;
private:
CString& wrapped;
};
Теперь компилятор не будет преобразовывать в CStringWrapper
автоматически. Конечно, это означает, что вы должны использовать CStringWrapper(mystring)
вызвать функции, которые принимают CString
, но я думаю, что это менее плохо, чем быть CString
,
Ну, я думаю, что это проблема 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
значения, а также сделал параметры в заданной функции const.
Я думаю, что компилятор VS6 просто находит первую перегрузку функции, которая будет делать, и использует это, даже если это не лучшее соответствие.