boost::lexical_cast + enum + unnamed namespace
-
Hallo Leute,
ich habe einen komischen Effekt bei der Ausgabe eines enums in einen (i)ostream. Das Verhalten von lexical_cast verändert sich, wenn ich die Ausgabefunktion für den enum in einen unnamed namesapce stecke.
Das ist der Code:
#include <iostream> #include <sstream> #include <boost/lexical_cast.hpp> class Foo { public: enum Side { top, bottom }; explicit Foo( Side side ) : m_side( side ) {} Side m_side; }; namespace // unnamed namespace! { std::ostream& operator<<( std::ostream& out, Foo::Side side ) { return out << (side == Foo::top? "top": "bottom"); } } int main() { using namespace std; Foo f( Foo::bottom ); cout << "Side: " << f.m_side << endl; stringstream buf; buf << "Side: " << f.m_side; cout << "stringstream [" << buf.str() << "]" << endl; cout << "lexical_cast [" << ("Side: " + boost::lexical_cast< std::string >( f.m_side )) << "]" << endl; return 0; }
und das ist die (unerwartete) Ausgabe:
Side: bottom stringstream [Side: bottom] lexical_cast [Side: 1]
d.h. der lexical_cast behandelt den enum wie einen int.
Lasse ich aber den unnamend namespace weg, so erhalte ich wie gewünscht:
Side: bottom stringstream [Side: bottom] lexical_cast [Side: bottom]
Ich habe das debuggt und gesehen, dass innerhalb des lexical_cast auch nur ein iostream verwendet wird, genau wie der sstream. Das sollte also keinen Unterschied machen.
Hat irgend jemand eine Erklärung?
Ich verwende VC8 und boost-1.38Gruß
Werner
-
Push: .. kein Experte online?
-
Werner Salomon schrieb:
Push: .. kein Experte online?
Dein
operator<<
im anonymen, lokalen Namensraum der Übersetzungseinheit ist auch nur in dieser bekannt. Beimstd::basic_stringstream<...>
in den Interna vonboost::lexical_cast
ist die Funktion daher nicht sichtbar. Der Compiler wählt hier daher den nächstbesten Typen (int). Für die Version ohne Namespace ist das hingegen nicht der Fall.Edit: Man, ich sollte mal einen Deutschkurs an der VHS besuchen.
-
Ev. hilft das weiter:
http://www.cprogramming.com/tutorial/namespaces.html
(Abschnitt über den anonymen Namespace.)Simon
-
Tachyon schrieb:
Dein
operator<<
im anonymen, lokalen Namensraum der Übersetzungseinheit ist auch nur in dieser bekannt.Danke für die Antwort.
Ich war bisher der Meinung, das alles was inkludiert wird, mit zu der Übersetzungseinheit dazu gehört - ist das nicht so?Gruß
Werner
-
theta schrieb:
Ev. hilft das weiter:
http://www.cprogramming.com/tutorial/namespaces.html
(Abschnitt über den anonymen Namespace.)Danke Simon,
stimmt; da steht explizit, dass der unnnamed namespace nur innerhalb der Datei Gültigkeit hat. Wieder was dazu gelernt.
Gruß
Werner
-
Werner Salomon schrieb:
theta schrieb:
Ev. hilft das weiter:
http://www.cprogramming.com/tutorial/namespaces.html
(Abschnitt über den anonymen Namespace.).. da steht explizit, dass der unnnamed namespace nur innerhalb der Datei Gültigkeit hat.
Und das scheint schlicht falsch zu sein!
Laut Stroustrup Kapitel 9 "Source Files and Programs" gehören alle #includes und aufgelösten Makros mit zu der Übersetzungseinheit (translation unit).
Dafür spricht auch, dass ein selbst gestrickter lexical_cast - in der einfachsten denkbaren Fassung - den Streaming-Operator im unnamed namespace findet.Es scheint vielmehr ein Problem mit der Reihenfolge innerhalb der Übersetzungseinheit zu sein. Aber erklären kann ich es mir nach wie vor nicht.
Gruß
Werner