Seite 1 von 1

[C++] Operator wird verdeckt

Verfasst: 10.04.2012, 23:28
von Jonathan
Ich habe den operator<< für eine Matrixklasse überladen. Jetzt habe ich eine Menge Code in meinem Namespace Mrl, der operator<< ist aber im globalen Namespace (sagt man so, oder?). Im Namespace Mrl sind zusätzlich 3 weitere operator<< Überladungen, für andere Klassen. Der cout Aufruf ist auch im Namespace Mrl.

Jetzt möchte ich cout mit meinem Operator benutzen, aber er wird nicht gefunden. Ich habe 2 Mögliche Lösungen gefunden, einmal meinen neuen Operator auch in den Namespace Mrl packen, oder aber der Operator explizit Aufrufen (::operator<< (cout, m_BoneTransforms);).

Etwas Code:

Code: Alles auswählen

//Mein neuer Operator:
template<typename T> std::ostream &
	operator << (std::ostream & Stream, const glm::detail::tmat4x4<T> & Mat)

//ein Operator in Mrl, Filename ist eine eigene Klasse, die anderen sehen ähnlich aus
inline std::ostream& operator<<(std::ostream &Stream, const Filename& file)

cout << m_BoneTransforms[i] << endl; //geht nicht
::operator<< (cout, m_BoneTransforms[i]); //geht

Ich habe keine Ahnung, ob die Operatoren im Namespace Mrl wirklich daran schuld sind, aber ich wüsste jetzt auch nicht, was sonst das Problem ist.

Re: [C++] Operator wird verdeckt

Verfasst: 11.04.2012, 00:10
von CodingCat
Ja, das ist etwas hässlich. Der C++-Standard schreibt vor, dass der Name Lookup zunächst in den Namespaces der Argumente (in deinem Fall std und glm::detail) beginnt, und dann die Namespaces des Aufruferkontexts von innen nach außen absucht. Soweit, so vernünftig. Leider schreibt der Standard ebenso vor, dass der Lookup schon dann nicht mehr weiter nach außen fortgesetzt wird, wenn ein passender NAME in einem der umschließenden Namespaces gefunden wurde. Die Überladungsauflösung findet erst im Anschluss statt. Das heißt, wenn der Compiler merkt, dass keiner der gefundenen Operatoren aus Mrl zu deinem Aufruf passt, ist der Name Lookup bereits beendet, weiter außen liegende Überladungen fehlen einfach.

Damit sollten Überladungen solcher allgemeinen Operatoren und Funktionen (Paradebeispiel std::swap) im Optimalfall in demselben Namespace liegen wie der Datentyp, für den überladen wird. Dein Operator müsste damit im glm-Namespace liegen, um sicher immer gefunden zu werden. Dies wiederum verletzt ein Stück weit die strikte Modularisierung von Bibliotheken durch Namespaces. Eine halbwegs akzeptable Alternative wäre ein using ::operator <<; im Mrl-Namespace.

Re: [C++] Operator wird verdeckt

Verfasst: 14.04.2012, 23:10
von Jonathan
Ah ok. Danke für die Erklärung, jetzt geht es. :)