I want to add swap functionality to two existing C++ classes. One class inherits from the other. I want each classes' instances to only be swappable with instances of the same class. To make it semi-concrete, say I have classes Foo and Bar. Bar inherits from Foo. I define Foo::swap(Foo&) and Bar::swap(Bar&). Bar::swap delegates to Foo::swap. I want Foo::swap to only work on Foo instances and Bar::swap to only work on Bar instances: I can't figure out how to enforce this requirement.
Here's a sample of what's giving me trouble:
#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;
}
Here's the output:
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
You can see in the final output group where f1.swap(b34) "sliced" b34 in a potentially nasty way. I'd like the guilty line to either not compile or blow up at runtime. Because of the inheritance involved, I think I run into the same problem if I use a nonmember or friend swap implementation.
The code is available at codepad if that helps.
This use case arises because I want to add swap to boost::multi_array and boost::multi_array_ref. multi_array inherits from multi_array_ref. It only makes sense to swap multi_arrays with multi_arrays and multi_array_refs with multi_array_refs.