Swap implentieren und durch die STL beuntzen lassen
-
Hallo,
die swap Funktion aus <algorithm> ist ja als Dreieckstausch implementiert. Dem Gegenüber stehen die swap Funktionen von zB Vektor oder std::string.
Algorithmen wie RandomShuffle oder BubbleSort profitieren bei Datentypen wie vector stark von Swap.
Wenn ich also einen Vector aus zB String mit RandomShuffle bearbeite, werden die Strings dann über Dreieckstausch getauscht oder wird hier das std::string::swap aufgerufen?
Wie muss ich eine swap Funktion für eigene Klassen implementieren, damit sie von Algorithmen der STL benutzt wird? Als freie Funktion wie swap aus Algorithm oder als Elementfunktion wie zB bei vector?class Klasse { public: void swap(Klasse& a){} //so? } void swap(Klasse& a, Klasse& b){} //oder so? std::vector<Klasse> vec; random_shuffle(vec.begin(), vec.end()); //wird hier MEIN swap verwendet?
-
namespace std { template<> void swap(Klasse& a, Klasse& b) { // ... } }
-
Ich habe mir ein kleines Testprogramm mit deinem Ansatz geschrieben:
#include <algorithm> #include <iostream> class Klasse { public: int i; }; namespace std { template<> void swap(Klasse& a, Klasse& b) { int tmp = a.i; a.i = b.i; b.i = tmp; std::cout<<"test"; } } #include <vector> using namespace std; int main() { Klasse t; vector<Klasse> vec; t.i = 7; vec.push_back(t); t.i = 2; vec.push_back(t); t.i = 5; vec.push_back(t); random_shuffle(vec.begin(), vec.end()); }Allerdings erhalte ich keine Ausgabe von "test" (Weder bei sort noch bei random_shuffle)
-
Schade! Bei mir wird zwei mal "test" ausgegeben. (Visual C++ 2008)
-
Stimmt. Mit dem Windowscompiler wird "testtest" ausgegeben, mit CodeBlocks nicht. Kann sich jemand vorstellen, woran das liegen könnte?
-
Hab mal in den Quellcode der Standardbibliothek von g++ geguckt. Dort wird in random_shuffle **iter_**swap benutzt.
-
Und in iter_swap wird swap nicht benutzt um den Tausch zu machen.
-
Aber ruft iter_swap nicht std::swap auf? (Zumindest laut C++ Reference: http://www.cplusplus.com/reference/algorithm/iter_swap/)
-
g++ 3.4.5 (MinGW):
template<typename _ForwardIterator1, typename _ForwardIterator2> inline void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType1; typedef typename iterator_traits<_ForwardIterator2>::value_type _ValueType2; const _ValueType1 __tmp = *__a; *__a = *__b; *__b = __tmp; }Visual C++ 2008:
template<class _FwdIt1, class _FwdIt2> inline void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right) { swap(*_Left, *_Right); }
-
Ist die G++-Implementierung wirklich so schlecht, dass sie jegliche
swap()-Funktionen auf Namensraum-Ebene einfach ignoriert?
Meiner Ansicht nach müsste
iter_swap(a, b)das Gleiche tun wieswap(*a, *b)-- im Idealfall mit ADL. Wenn man nun aufgrund von Exceptionsicherheit oder Performance gezwungen wird, immer die zweite Möglichkeit zu wählen, finde ichstd::iter_swap()etwas witzlos.
-
Vielleicht sollte man sich vor Augen halten, dass das die Implementierung aus dem 3.4.5 gcc ist. Mittlerweile ist der 4.4.2 aktuell.
MinGW ist einfach chronisch veraltet.Bei meinem g++ wird hier auch wie gewünscht zwei mal test ausgegeben.
-
Jau mit g++ 4.4.1 für Windows ( http://www.tdragon.net/recentgcc/ ) funktionierts auch.
-
Okay, dann ist ja alles in Ordnung. Hat mich nur gerade etwas gewundert...

-
YASC schrieb:
Vielleicht sollte man sich vor Augen halten, dass das die Implementierung aus dem 3.4.5 gcc ist. Mittlerweile ist der 4.4.2 aktuell.
MinGW ist einfach chronisch veraltet.Das war mal.