&
zu bekommen, um eine Adresse einer Variablen zu erhalten, kann problematisch sein, wenn der Variablentyp operator&()
überlastet ist. Zum Beispiel _com_ptr_ hat operator&()
überladen mit einem Nebeneffekt der Modifizierung des Objekts.Die meisten portablen und zuverlässigen Weg, um die Adresse der Variablen in C++
Jetzt habe ich eine komplizierte Reihe von Vorlagen mit Funktionen wie folgt aus:
template<class T>
void process(const T* object)
{
//whatever
}
template<class T>
void tryProcess(T& object)
{
process(&object)
}
In tryProcess()
I T
einen T*
Zeiger hält die Adresse des tatsächlichen Objekt vom Typ erhalten müssen.
Die obige Implementierung von tryProcess()
funktioniert nur in Ordnung, wenn class T
operator&()
nicht überlastet ist. Also wenn ich tryProcess<_com_ptr_<Interface>>()
rufe kann ich unerwartete Ergebnisse bekommen - der überladene operator&()
wird ausgelöst.
In another question die folgende Problemumgehung ist suggested:
template<class T>
T* getAddress(T& object)
{
return reinterpret_cast<T*>(&reinterpret_cast<char&>(object));
}
Mit einer solchen Funktion, die ich tryProcess()
implementieren lassen sich wie folgt:
template<class T>
void tryProcess(T& object)
{
process(getAddress(object))
}
und wird immer das gleiche Verhalten unabhängig davon, ob class T
hat operator&()
überladen. Dies führt zu Null Overhead mit Optimierungen für Visual C++ 7 - der Compiler erhält, was zu tun ist, und ruft nur die Objektadresse ab.
Wie tragbar und Standard-Compilant ist diese Lösung für das Problem? Wie könnte es verbessert werden?
Als Referenz für spätere Leser: C++ 11 standardisierte eine ordentlich umschlossene Version dieses Idioms als "std :: addressof": http://en.cppreference.com/w/cpp/ memory/addressof' –