1

I'm using private inheritance in the implementation of two very related classes. The using Base::X; is very useful and elegant. However, I can't seem to find an elegant solution for reusing the base class's swap function.

class A
{
public:
   iterator       begin();
   const_iterator begin() const;
   const_iterator cbegin() const;

   A clone();

   void swap( A& other );
};

class Const_A : private A
{
public:
   // I think using A::A; will be valid in C++0x
   Const_A( const A& copy) : A(copy) { }

   // very elegant, concise, meaningful
   using A::cbegin;

   // I'd love to write using A::begin;, but I only want the const overload
   // this is just forwarding to the const overload, still elegant
   const_iterator begin() const
   { return A::begin(); }

   // A little more work than just forwarding the function but still uber simple
   Const_A clone()
   { return Const_A(A::clone()); }

   // What should I do here?
   void swap( Const_A& other )
   { /* ??? */ }
};

So far the only thing I can come up with is copy-pasting A::swap's definition into Const_A::swap's definition, YUCK!

Is there an elegant solution to to reuse the private base class's swap?

Is there a cleaner way to implement what I'm trying to do here (a const wrapper for a class)?

alain.janinm
  • 19,951
  • 10
  • 65
  • 112
deft_code
  • 57,255
  • 29
  • 141
  • 224
  • Did you mean to return `iterator` (instead of `const_iterator`!) for `begin`? Otherwise I don’t see the sense in having two functions, and to override the function in your derived class. – Konrad Rudolph Oct 27 '10 at 18:36
  • `std::vector<>::begin() -> iterator` and `std::vector<>::begin() const -> const_iterator`. This is exactly what I did and my classes have similar semantics. Am I misunderstanding your question? – deft_code Oct 27 '10 at 18:54
  • got it, you’re right. But what is the `cbegin` method for, then? – Konrad Rudolph Oct 27 '10 at 18:55
  • Why not just use `const A` in place of `Const_A`? @Konrad: AFAIK, it's for the problem where this might be "unsafe" to me: `for (auto i = cont.begin(); ...)` because of `cont` is non-const, I get a mutable iterator, even if I don't want to mutate the elements. I could cast a `const` into the container use then use `begin`, or just use `cbegin`. – GManNickG Oct 27 '10 at 18:57
  • @GMan: My class has the same problem that `iterator` does for the standard containers. `iterator == byte*`, `const iterator == byte* const` and `const_iterator == const byte*`. I have similar semantics for my code. – deft_code Oct 27 '10 at 19:20

2 Answers2

5

Well, can’t you just call the base’s version of swap?

void swap( Const_A& other )
{
    A::swap(other); // swaps the `A` portion of `this`.
    // …
}

In place of , you’d normally swap the members pertaining only to Const_A, not A but since there aren’t any in your particular case, this is all that you should need.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
3

You can do as with the rest of the methods:

void Const_A::swap( Const_A& other ) {
   A::swap(other);
   // here any specifics
}
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489