Ist dieser Code Standard-C++? (std::swap überladung als friend einer Klasse)
-
Ah, okay, jetzt hab ichs
Besten Dank 
-
Cyres schrieb:
Floor** floor_;<sarkasmus>Ich glaube, da fehlt noch ein Sternchen.</sarkasmus>

-
krümelkacker schrieb:
Cyres schrieb:
Floor** floor_;<sarkasmus>Ich glaube, da fehlt noch ein Sternchen.</sarkasmus>

ogottogottogott, jetzt werden hier krümel gekackt!
bin dann schnell mal weg *regenschirm aufspann*
-
krümelkacker schrieb:
Cyres schrieb:
Floor** floor_;<sarkasmus>Ich glaube, da fehlt noch ein Sternchen.</sarkasmus>

[sarkasmus]HTML ist hier aber nicht erlaubt ;)[/sarkasmus]
Ja, aber wenn man ein Array in ein Array packt (STL) braucht man keine Pointer und somit swap-Funktion nicht
-
Guten Morgen!
Cyres schrieb:
Allerdings benutzt die STL std::swap und kommt an meinen Namespace bzw. eine Swap-Funktion ohne NameSpace nicht dran.
Kannst Du mir bitte mal ein Beispiel nennen, wo das Problem auftritt? Also: wo die STL std::swap() aufruft und nicht einfach swap(), das Deine Version per ADL aufgreift?!
Ich sehe das Problem gerade nicht...
-
Furble Wurble schrieb:
Guten Morgen!
Cyres schrieb:
Allerdings benutzt die STL std::swap und kommt an meinen Namespace bzw. eine Swap-Funktion ohne NameSpace nicht dran.
Kannst Du mir bitte mal ein Beispiel nennen, wo das Problem auftritt? Also: wo die STL std::swap() aufruft und nicht einfach swap(), das Deine Version per ADL aufgreift?!
Ich sehe das Problem gerade nicht...
C++03 kannte noch keine Bedingungen für "Swappable", jeder Verweis auf swap bezog sich daher auf std::swap und eine Implementation hatte es zu unterlassen, ggf. eine Funktion per ADL auszuwählen.
In C++11 ist das anders. Hier müssen durch die Standardbibliothek immer auch Nonmemberswapfunktionen per ADL berücksichtigt werden (17.6.3.2). Eine Spezialisierung in std ist dann also häufig nicht mehr erforderlich.
-
// ohne Namespace namespace std { template<> void swap(Room& rhs, Room& lhs) { swap(rhs, lhs); } } // mit Namespace namespace std { template<> void swap(Room& rhs, Room& lhs) { MySpace::swap(rhs, lhs); } }Was scheinbar noch nicht aufgefallen ist: Wenn es sich um MySpace::Room handelt, dann ist für beide definitionen entweder ein geöffneter namespace MySpace oder ein using namespace MySpace nötig. Im ersten Fall würde man MySpace::Std::swap<Room> definieren, was nicht der Absicht entspricht (und außerdem den Compiler veranlassen würde, die Spezialisierung ohne Deklaration des allgemeinen Templates MySpace::swap abzulehnen). Im zweiten Fall hätte man vor/in einen Header eine using-Direktive geschrieben, was böse ist. Also bitte MySpace::Room voll qualifizieren, ohne usings & Co.
-
Deshalb meine Frage zuerst. Evtl. sollte der ursprüngliche Beitrag diesbzgl. nochmal edietiert werden, so ist er nämlich nicht so gut verständlich.
-
camper schrieb:
Furble Wurble schrieb:
Guten Morgen!
Cyres schrieb:
Allerdings benutzt die STL std::swap und kommt an meinen Namespace bzw. eine Swap-Funktion ohne NameSpace nicht dran.
Kannst Du mir bitte mal ein Beispiel nennen, wo das Problem auftritt? Also: wo die STL std::swap() aufruft und nicht einfach swap(), das Deine Version per ADL aufgreift?!
Ich sehe das Problem gerade nicht...
C++03 kannte noch keine Bedingungen für "Swappable", jeder Verweis auf swap bezog sich daher auf std::swap und eine Implementation hatte es zu unterlassen, ggf. eine Funktion per ADL auszuwählen.
In C++11 ist das anders. Hier müssen durch die Standardbibliothek immer auch Nonmemberswapfunktionen per ADL berücksichtigt werden (17.6.3.2). Eine Spezialisierung in std ist dann also häufig nicht mehr erforderlich.Es gibt ja eine Überladung von
swap()fürMySpace::MyRoom&, mir wäre jetzt nicht bekannt, dass c++03, c++11 hin oder her, noch eine Spezialisierung in std:: vonnöten ist. (Darum auch meine Bitte ein Beispiel für das Problem dass die zusätzliche Spezialisierung löst.)Und warum sollte swap() mit user-defined types in C+03 nicht ADL benutzen? Mir schwant ein Missverständnis.
-
Furble Wurble schrieb:
Und warum sollte swap() mit user-defined types in C+03 nicht ADL benutzen? Mir schwant ein Missverständnis.
Sofern in deinem Code ein Ausdruck der Form
swap(foo, bar)auftritt, wird natürlich schon immer ADL eingesetzt (sofern nicht sinnloserweise eine ungeeignete swap-Deklaration beim unqualifizierten Lookup gefunden wird).
Die Aussage ist die, dass die Algorithmen der Standardbibliothek, die selbst swap benutzen, in C++03 grundsätzlich nur das in std befindliche swap berücksichtigen dürfen.
Die Logik dahinter ist indirekt:
1. der alte Standard spezifiziert nicht ausdrücklich, das ADL genutzt werden soll,
2. der alte Standard spezifiziert auch keine Beschränkungen/bestimmtes Verhalten für non-member-swap für UDTs,
3. käme ADL zum Einsatz und würde ein Algorithmus der Standardbibliothek eine solche nicht in std befindliche Funktion aufrufen, wäre nicht mehr garantiert (wegen 2.), dass dieser Algorithmus das richtige tut.Meistens steht ohnehin nicht dabei, dass swap benutzt werden soll; man denke z.B. an std::sort.
-
camper schrieb:
Die Aussage ist die, dass die Algorithmen der Standardbibliothek, die selbst swap benutzen, in C++03 grundsätzlich nur das in std befindliche swap berücksichtigen dürfen.
Die Logik dahinter ist indirekt:
1. der alte Standard spezifiziert nicht ausdrücklich, das ADL genutzt werden soll,
2. der alte Standard spezifiziert auch keine Beschränkungen/bestimmtes Verhalten für non-member-swap für UDTs,
3. käme ADL zum Einsatz und würde ein Algorithmus der Standardbibliothek eine solche nicht in std befindliche Funktion aufrufen, wäre nicht mehr garantiert (wegen 2.), dass dieser Algorithmus das richtige tut.Meistens steht ohnehin nicht dabei, dass swap benutzt werden soll; man denke z.B. an std::sort.
Evtl. kann man das aus dem Standard herauslesen, weil nur für std::swap ein Effekt und die Bedingungen aufgeführt sind. Die gesamten spezialisierten swap()s verweisen dann auf std::swap.
Eine Implementierung, die sicher spielen will, sollte also von Überladungen die Finger lassen - kann ja sein, dass swap() nicht gleich swap ist.
Mein gcc 4.6.1 freut sich allerdings ueber die Muehe, die ich mir gemacht habe (kompiliert mit
-std=c++03):#include <iterator> #include <algorithm> #include <iostream> #include <cstddef> namespace Furble{ struct Wurble{ int i; void swap(Wurble& x) { using std::swap; // bring into scope swap(i, x.i); // use whatever fits best... std::cout << "Furble::Wurble::swap()\n"; } }; void swap(Wurble& x, Wurble& y){ x.swap(y); } std::ostream& operator<<(std::ostream& os, const Wurble& w) { return os << w.i; } } template<typename T, std::size_t N> T* begin(T(&arr)[N]) { return arr; } template<typename T, std::size_t N> T* end(T(&arr)[N]) { return arr+N; } int main(){ using Furble::Wurble; Wurble arr[] = {{1},{2},{3},{4},{5},{6},{7}}; std::copy(begin(arr), end(arr), std::ostream_iterator<Wurble>(std::cout << "before:\t", " ")); std::cout << '\n'; std::reverse(begin(arr), end(arr)); std::copy(begin(arr), end(arr), std::ostream_iterator<Wurble>(std::cout << "after:\t", " ")); std::cout << '\n'; }
-
begin und end gibt es schon in <iterator>
-
camper schrieb:
begin und end gibt es schon in <iterator>
Danke - aber ich habe für C++03 getestet.