swap<std::vector<t>>(r, l); ist falsch. Gäbe es eine solche Spezialisierung tatsächlich, so müsstest du zumindest
std:: davorschreiben, um nicht deine eigene Swap-Funktion rekursiv mit
GpuMemory<std::vector<std::vector<std::vector<...>>>> aufzurufen. Tatsächlich vermeidet man Funktionsspezialisierungen allerdings nach Möglichkeit komplett, weil Überladungen dieselbe Funktionalität intuitiver und konsistenter bieten.
Hast du zwei Vektoren
l und
r, dann findet ein unqualifizertes
swap(l, r) per Argument-dependent Lookup von ganz alleine die richtige
Überladung im
std-Namespace. In deinem Beispiel müsstest du zur Vermeidung von Rekursion allerdings
l/
r von Hand in reine Vektoren casten:
swap(static_cast<std::vector<b>&>(l) , static_cast<std::vector<b>&>(r)). Alternativ könntest du
std::swap(l, r) aufrufen, weil du den Namespace der Vektorklasse in diesem Fall kennst und er nicht mit deinem aktuellen Namensraum überlappt.
Die STL bietet neben der freien Swap-Funktion in der Regel auch eine Objektfunktion an, so kommen die Klassen einerseits ohne
friend aus und vereinfachen andererseits die Notation bei Komposition und Vererbung:
Code: Alles auswählen
// std::vector-Vererbung aus Frage-Beitrag übernommen, NICHT EMPFOHLEN
template<typename t> class GpuMemory : public std::vector<t>
{
typedef std::vector<t> base_type;
public:
void swap(GpuMemory<b> &r)
{
using std::swap;
this->base_type::swap(r);
swap(m_GpuPointer, r.m_GpuPointer);
swap(m_LastAllocatedSize, r.m_LastAllocatedSize);
}
};
template<typename b> void swap(GpuMemory<b>& l, GpuMemory<b>& r) { l.swap(r); }
Der gezeigte Code ist als generisches Beispiel für den Umgang mit Swap in Vererbungshierarchien gedacht, von einer Vererbungsbeziehung mit Containerklassen rate ich grundsätzlich ab. Dasselbe lässt sich ohne Funktionalitätseinbußen wesentlich klarer durch einfache öffentliche Komposition umsetzen. Dann bist du auf einen Schlag die ganzen Vererbungsverwirrungen los:
Code: Alles auswählen
template<typename t> class GpuMemory
{
...
public:
typedef std::vector<t> data_type;
data_type data;
void swap(GpuMemory<b> &r)
{
using std::swap;
swap(data, r.data);
swap(m_GpuPointer, r.m_GpuPointer);
swap(m_LastAllocatedSize, r.m_LastAllocatedSize);
}
};
template<typename b> void swap(GpuMemory<b>& l, GpuMemory<b>& r) { l.swap(r); }
// Anwendercode nutzt für Vektorfunktionalität jetzt gpumemory.data.push_back/resize/... statt gpumemory.push_back/resize/...