jak zapewnić funkcję swap dla mojej klasy?
Jak poprawnie włączyć moje swap
w algorytmach STL?
1) członek swap
. Czy std::swap
używa sztuczki SFINAE, aby użyć członka swap
.
2) wolnostojący swap
w tej samej przestrzeni nazw.
3) częściowa specjalizacja std::swap
.
EDIT: wygląda na to, że nie wyraziłem jasno swojego pytania. Zasadniczo, mam klasę szablonu i potrzebuję STL algos, aby użyć (wydajnej) metody swap, którą napisałem dla tej klasy.
2 answers
1) jest właściwym użyciem z swap
. Zapisz to w ten sposób, gdy piszesz kod "library" i chcesz włączyć ADL (wyszukiwanie zależne od argumentów) na swap
. Ponadto nie ma to nic wspólnego z SFINAE.
// some algorithm in your code
template<class T>
void foo(T& lhs, T& rhs){
using std::swap; // enable 'std::swap' to be found
// if no other 'swap' is found through ADL
// some code ...
swap(lhs, rhs); // unqualified call, uses ADL and finds a fitting 'swap'
// or falls back on 'std::swap'
// more code ...
}
2) jest właściwym sposobem zapewnienia swap
funkcji dla twojej klasy.
namespace Foo{
class Bar{}; // dummy
void swap(Bar& lhs, Bar& rhs){
// ...
}
}
Jeśli swap
jest teraz używany, jak pokazano w 1), twoja funkcja zostanie znaleziona. Ponadto, możesz uczynić tę funkcję przyjacielem, jeśli koniecznie musisz, lub podać członka swap
, który jest wywoływany przez funkcja swobodna:
// version 1
class Bar{
public:
friend void swap(Bar& lhs, Bar& rhs){
// ....
}
};
// version 2
class Bar{
public:
void swap(Bar& other){
// ...
}
};
void swap(Bar& lhs, Bar& rhs){
lhs.swap(rhs);
}
3) masz na myśli wyraźną specjalizację. Partial jest jeszcze czymś innym i nie jest możliwe dla funkcji, tylko structs / classes. Jako takie, ponieważ nie możesz specjalizować się std::swap
w klasach szablonów, musisz zapewnić wolną funkcję w swojej przestrzeni nazw. Nie jest źle, jeśli mogę tak powiedzieć. Obecnie możliwa jest również wyraźna specjalizacja, ale ogólnie nie chcesz specjalizować szablonu funkcji :
namespace std
{ // only allowed to extend namespace std with specializations
template<> // specialization
void swap<Bar>(Bar& lhs, Bar& rhs){
// ...
}
}
4) Nie, ponieważ 1) różni się od 2) i 3). Ponadto posiadanie zarówno 2), jak i 3) doprowadzi do zawsze posiadania 2) picked, ponieważ lepiej pasuje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-12 13:21:33
Aby odpowiedzieć na edycję, gdzie klasy mogą być klasami szablonowymi, w ogóle nie potrzebujesz specjalizacji. rozważ klasę taką jak Ta:
template <class T>
struct vec3
{
T x,y,z;
};
Można zdefiniować klasy takie jak:
vec3<float> a;
vec3<double> b;
vec3<int> c;
Jeśli chcesz być w stanie stworzyć jedną funkcję do zaimplementowania wszystkich 3 swapów (Nie żeby ta przykładowa Klasa tego gwarantowała), robisz tak jak Xeo powiedział w (2)... bez specjalizacji, ale wystarczy zrobić zwykłą funkcję szablonu:
template <class T>
void swap(vec3<T> &a, vec3<T> &b)
{
using std::swap;
swap(a.x,b.x);
swap(a.y,b.y);
swap(a.z,b.z);
}
Funkcja szablonu swap powinna znajdować się w tym samym przestrzeń nazw jako klasa, którą próbujesz zamienić. poniższa metoda znajdzie i użyje tego swapu, nawet jeśli nie odwołujesz się do tej przestrzeni nazw za pomocą ADL:
using std::swap;
swap(a,b);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-15 02:08:19