Я хочу добавить функциональность подкачки к двум существующим классам C ++. Один класс наследует от другого. Я хочу, чтобы экземпляры каждого класса можно было заменять только экземплярами одного и того же класса. Для полубетона, скажем, у меня есть классы Foo и Bar. Бар наследует от Foo. Я определяю Foo :: swap (Foo &) и Bar :: swap (Bar &). Bar :: swap делегаты Foo :: swap. Я хочу, чтобы Foo :: swap работал только на экземплярах Foo, а Bar :: swap работал только на экземплярах Bar: я не могу понять, как применить это требование.
Вот пример того, что доставляет мне неприятности:
#include <algorithm>
#include <iostream>
struct Foo {
int x;
Foo(int x) : x(x) {};
virtual void swap(Foo &other) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::swap(this->x, other.x);
};
};
struct Bar : public Foo {
int y;
Bar(int x, int y) : Foo(x), y(y) {};
virtual void swap(Bar &other) {
std::cout << __PRETTY_FUNCTION__ << " ";
Foo::swap(other);
std::swap(this->y, other.y);
};
};
void display(Foo &f1, Foo &f2, Bar &b34, Bar &b56)
{
using namespace std;
cout << "f1: " << f1.x << endl;
cout << "f2: " << f2.x << endl;
cout << "b34: " << b34.x << " " << b34.y << endl;
cout << "b56: " << b56.x << " " << b56.y << endl;
}
int main(int argc, char **argv)
{
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "Initial values: " << std::endl;
display(f1,f2,b34,b56);
}
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "After Homogeneous Swap: " << std::endl;
f1.swap(f2); // Desired
b34.swap(b56); // Desired
display(f1,f2,b34,b56);
}
{
Foo f1(1), f2(2);
Bar b34(3,4), b56(5,6);
std::cout << std::endl << "After Heterogeneous Member Swap: " << std::endl;
// b56.swap(f2); // Doesn't compile, excellent
f1.swap(b34); // Want this to not compile, but unsure how
display(f1,f2,b34,b56);
}
return 0;
}
Вот вывод:
Initial values:
f1: 1
f2: 2
b34: 3 4
b56: 5 6
After Homogeneous Swap:
virtual void Foo::swap(Foo&)
virtual void Bar::swap(Bar&) virtual void Foo::swap(Foo&)
f1: 2
f2: 1
b34: 5 6
b56: 3 4
After Heterogeneous Member Swap:
virtual void Foo::swap(Foo&)
f1: 3
f2: 2
b34: 1 4
b56: 5 6
Вы можете видеть в окончательной группе вывода, где f1.swap (b34) «нарезал» b34 потенциально неприятным способом. Я бы хотел, чтобы виновная строка не компилировалась или не взорвалась во время выполнения. Из-за вовлеченного наследования, я думаю, я столкнусь с той же проблемой, если использую реализацию подкачки не-члена или друга.
Код доступен по адресу codepad , если это поможет.
Этот вариант использования возникает потому, что Я хочу добавить swap для boost :: multi_array и boost :: multi_array_ref . multi_array наследуется от multi_array_ref. Имеет смысл только менять multi_arrays на multi_arrays и multi_array_refs на multi_array_refs.