2013-02-04 3 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); 

OK 다음 작품 :

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 

우리는 비주얼 스튜디오 6을 사용하는 우리의 컴파일러 (아니오, Windows XP와 7에서는 업그레이드가 내가 원하는 것만 큼 많은 옵션이 아닙니다).

+1

이것은 컴파일러의 심각한 버그처럼 보입니다. 명시 적 타입 변환 (필요하지 않은 경우 이벤트)을 시도 했습니까? 또한, 과부하 중 어떤 것이'const CString &'이 있든 없든? –

+1

대부분의 소위 C++ 컴파일러는 완전히 표준에 부합하지 않지만 MSVC 6은 너무 오래되어 깨져서 C++ 컴파일러로 불릴 자격이 없습니다. 또한 일반적으로 표준 C++을 기반으로하므로 질문에 대한 답변이 VC6에서 작동하지 않을 수도 있습니다. – 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 함수에서 참조를 제거하고 set 함수 const에서도 params를 만들었습니다.

VS6 컴파일러는 가장 잘 맞는 것이 아닐지라도 첫 번째 함수 오버로드를 찾아 사용한다고 생각합니다.

+0

내 생각에 컴파일러 버그 인 것 같습니다. –

2

이것은 CString이 다른 유형에서 생성 될 수 있다는 사실 때문에 발생한다고 생각합니다. CString 버전을 다른 서명으로 만들 필요가있을 수 있습니다. 아마도 다른 정수 또는 그와 같은 것을 추가하십시오.

그러나 더 좋은 해결책은 다른 사람이 적합 할 때도 컴파일러가 자동으로 CString 버전을 선택하지 않도록 CString에 대한 래퍼를 만드는 것입니다. 예를 들어

,

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

지금, 컴파일러가 자동으로 CStringWrapper로 변환되지 않습니다. 물론 CStringWrapper(mystring)을 사용하여 CString을 사용하는 함수를 호출해야한다는 것을 의미합니다. 그러나 evyerthing이 CString 인 것보다 나쁘지 않다고 생각합니다.

+0

CString으로 변환 할 수있는 모든 것이 맞다고 생각합니다. 함수 선언의 순서를 변경하면 먼저 선호하는 메서드를 찾은 다음 끝에 CString을 사용한다는 사실을 알게되었습니다. – fwgx