While striving for const-correctness, I often find myself writing code such as this
class Bar;
class Foo {
public:
  const Bar* bar() const { /* code that gets a Bar somewhere */ }
  Bar* bar() {
    return const_cast< Bar* >(
      static_cast< const Foo* >(this)->bar());
  }
};
for lots of methods like bar(). Writing these non-const methods which call the const ones by hand is tedious; besides, I feel I am repeating myself – which makes me feel bad.
What can I do to alleviate this task? (Macros and code generators are not allowed.)
Edit: Besides litb's solution I also like my own. :)
Casting away const relies on the caller only using the function on non-const objects. A potential solution is to alter the code in // .... so that it doesn't need to use the object's "current color". Add versions of all the functions you use, that take a QColor parameter instead.
const function use cases A const function can be called by either a const or non- const object. Only a non- const object can call a non- const function; a const object cannot call it.
const member functions may be invoked for const and non-const objects. non-const member functions can only be invoked for non-const objects. If a non-const member function is invoked on a const object, it is a compiler error.
Yes, in the sense that it can be const_cast away, or the object can have mutable members.
Another way could be to write a template that calls the function (using CRTP) and inherit from it.
template<typename D>
struct const_forward {
protected:
  // forbid deletion through a base-class ptr
  ~const_forward() { }
  template<typename R, R const*(D::*pf)()const>
  R *use_const() {
    return const_cast<R *>( (static_cast<D const*>(this)->*pf)() );
  }
  template<typename R, R const&(D::*pf)()const>
  R &use_const() {
    return const_cast<R &>( (static_cast<D const*>(this)->*pf)() );
  }
};
class Bar;
class Foo : public const_forward<Foo> {
public:
  const Bar* bar() const { /* code that gets a Bar somewhere */ }
  Bar* bar() { return use_const<Bar, &Foo::bar>(); }
};
Note that the call has no performance lost: Since the member pointer is passed as a template parameter, the call can be inlined as usual.
Use following trick:
class Bar;
class Foo {
public:  
  Bar* bar() { 
    // non-const case
    /* code that does something */ 
  }  
  const Bar* bar() const {    
      return This().bar();  // use non-const case
   }
private:
  //trick: const method returns non-const reference
  Foo & This() const { return const_cast<Foo &>(*this); } 
};
Note it is possible to use unique function This for any const/non-const functions.
Alternative solution without static_cast (but I prefer the first one):
class Bar;
class Foo {
public:  
  const Bar* bar() const { /* code that does something */ }  
  Bar* bar() { return const_cast<Bar*>(cthis().bar()); } // use const case
private:
  const Foo & cthis() const { return *this; } 
};
                        You can do something like this:
class Bar;
class Foo {
public:
  const Bar* bar() const { return getBar(); }
  Bar* bar() {
   return getBar();
  }
  private:
    Bar* getBar() const {/* Actual code */ return NULL;}
};
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With