C++ templates & call by reference

Hallo!

Heute bin ich auf ein interessantes C+±Phänomen unter Microsoft Visual Studio 2008 gestoßen.

Kurze Erklärung des Falles:
Ich habe mehrere Aufrufe einer Methode namens ReadValue für verschiedene Typen. Da die Verwaltung von mehreren Methoden & eine Kodeverlängerung unerwünscht sind, habe ich eine Vorgabe-Methode (sprich template) implementiert.

Die Methode hat den Aufruf

template
bool ReadValue(const LPCTSTR szName, T &nValue, const T nDefValue);

und verwendet wie man sieht call by reference.

Das Problem:
Heute musste ich feststellen, dass die Methode zwar brav die Werte einliest, den Wert aber über den Übergabeparameter nValue nicht zurückgibt. Als ich die sechs normalen Methoden ReadValue für die unterschiedlichen Typen (BYTE, float, int, UINT, WORD, …) hinzufügte & die Vorlagenmethode ReadValue auskommentierte, ging alles wie erwünscht: Der Wert wurde zurückgegeben.

Frage:
Was mache ich falsch?

Hier der Kode im Detail:

// ---------------------------------------------------------------------------------------------------------------
// Base functionality of getting a number from the data file.
// Parameters:
// szName : String of the name to be searched in the data file.
// nValue : Value to be returned
// nDefault: Value to be taken, if the nValue does not exist in the data file.
// Returns whether the reading was successful of not.
// 20100213 SAE
// ---------------------------------------------------------------------------------------------------------------
template
bool CPSDatFile::ReadValue(const LPCTSTR szName, T &nValue, const T nDefault)
{
bool bValueRead = false;
stlString strBuffer;

if(ReadValue(szName, strBuffer, „“))
{
nValue = (T)_tstof(strBuffer.c_str());
bValueRead = true;
}
else
{
nValue = nDefault;
}

return bValueRead;
}

Hi,

hast du es schon mit Dereferenzierung versucht? Versuch doch einmal folgendes:


T* nVal_ptr = &nValue
// nun nVal_ptr die Strings geben

Danke für die rasche Antwort!

Habe es wie folgt versucht:

template
bool CPSDatFile::ReadValue(const LPCTSTR szName, T &nValue, const T nDefault)
{
bool bValueRead = false;
stlString strBuffer;
T* pValue = &nValue;

if(ReadValue(szName, strBuffer, „“))
{
pValue = (T*)_tstof(strBuffer.c_str());
bValueRead = true;
}
else
{
pValue = (T*)&nDefault;
}

return bValueRead;
}

Allerdings mag der Übersetzter das irgendwie nicht:

1>d:\arbeit\vc2008\cogniplus\visp\win32\read.cpp(195) : error C2440: ‚Typumwandlung‘: ‚double‘ kann nicht in ‚short *‘ konvertiert werden
1> d:\arbeit\vc2008\cogniplus\visp\win32\algorithm.cpp(992): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template „bool CPSDatFile::ReadValue(const LPCTSTR,T &,const T)“.
1> with
1> [
1> T=short
1> ]

Ohne den Zeiger ging es zwar, aber der Wert blieb nach erfolgreichem Abschluss der Methode unverändert.

LG

Hallo Sae,

ich habe folgendes angedacht:

template
bool CPSDatFile::ReadValue(const LPCTSTR szName, T &nValue, const T nDefault)
{
bool bValueRead = false;
stlString strBuffer;
T* pValue = &nValue;

if(ReadValue(szName, strBuffer, „“))
{
pValue = (T*)_tstof(strBuffer.c_str());
bValueRead = true;
}
else
{
*pValue = nDefault; //*pValue anstatt pValue
}

return bValueRead;
}

Ich werde mir das später nochmal anschauen.
Viele Grüße

Hallo!

Hier mein Versuch:

template
bool CPSDatFile::ReadValue(const LPCTSTR szName, T &nValue, const T nDefault)
{
bool bValueRead = false;
stlString strBuffer;
T* pValue = &nValue;

if(ReadValue(szName, strBuffer, „“))
{
pValue = (T*)_tstof(strBuffer.c_str());
bValueRead = true;
}
else
{
*pValue = nDefault;
}

return bValueRead;
}

Die Meldungen:

1>d:\arbeit\vc2008\cogniplus\visp\win32\read.cpp(195) : error C2440: ‚Typumwandlung‘: ‚double‘ kann nicht in ‚short *‘ konvertiert werden
1> d:\arbeit\vc2008\cogniplus\visp\win32\algorithm.cpp(988): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template „bool CPSDatFile::ReadValue(const LPCTSTR,T &,const T)“.
1> with
1> [
1> T=short
1> ]
1>d:\arbeit\vc2008\cogniplus\visp\win32\read.cpp(195) : error C2440: ‚Typumwandlung‘: ‚double‘ kann nicht in ‚WORD *‘ konvertiert werden
1> d:\arbeit\vc2008\cogniplus\visp\win32\algorithm.cpp(992): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template „bool CPSDatFile::ReadValue(const LPCTSTR,T &,const T)“.
1> with
1> [
1> T=WORD
1> ]
1>d:\arbeit\vc2008\cogniplus\visp\win32\read.cpp(195) : error C2440: ‚Typumwandlung‘: ‚double‘ kann nicht in ‚BYTE *‘ konvertiert werden
1> d:\arbeit\vc2008\cogniplus\visp\win32\algorithm.cpp(1017): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template „bool CPSDatFile::ReadValue(const LPCTSTR,T &,const T)“.
1> with
1> [
1> T=BYTE
1> ]

usw… Scheint sich wohl um einen Bug zu handlen, oder? Denn bei STL gibt es meines Wissens keinerlei Einschränkung bzgl. Vorlagen (templates).

Danke, Maurice, dass du dich darum kümmerst!

Hey, kein Problem :wink: Falls du eine Lösung gefunden hast, kannst du mir diese ja mitteilen. Sorry, dass ich dir nicht viel weiterhelfen konnte.

Viele Grüße

Es tut mir leid, aber ich kann dir da leider nicht helfen.