5

How to avoid

template <typename Derived>
struct base { int foo() { return static_cast<Derived*>(this)->bar(); } };

struct derived : base<derived> { int bar(); };        
struct another_derived : base<derived> { int bar(); };  // error: wrong base

without additional code in derived classes?

This has been asked twice before (though without the extra condition of avoiding additional code in derived classes), with the recommended answer

template <typename Derived>
struct base {
  int foo() { return static_cast<Derived*>(this)->bar(); } 
private:
  ~base() {}
  friend Derived;
};

However, this not only secures against above error, but also makes all private members of Base accessible from Derived. Is there an alternative, which avoids that? Or can it be conclusively shown that this is impossible?


edit

I actually have a more complex problem, where in addition to usual usage (as above) there is also

template<typename Derived>
struct intermediate : base<Derived>
{
  int bar() { return static_cast<Derived*>(this)->ark(); }
};

when the private destructor trick fails (since intermediate is not befriended by base).

Community
  • 1
  • 1
Walter
  • 44,150
  • 20
  • 113
  • 196
  • Read the answer below the "recommended answer" you linked. This solve the problem, not in the ideal way, but at first sight it seems like way better than the private dtor + friendship. – Melkon Nov 19 '15 at 15:15
  • @Melkon I have seen that answer, but it comes with additional code in the derived classes, which I wanted to avoid if possible. But it may be the only viable solution (see my edit). – Walter Nov 19 '15 at 15:33
  • `static_assert(std::is_base_of, Derived>::value, "");`http://en.cppreference.com/w/cpp/types/is_base_of – zahir Nov 19 '15 at 16:04
  • @zahir that does not work here, consider the example: `base` itself is perfectly okay, it's just the wrong base class. – Walter Nov 19 '15 at 16:15
  • @Walter: I know it's not ideal, but it's forced to the programmer who write Derived. He just can't forget to do it. I don't think an ideal solution is exist, since Base class know nothing about who derives from it, i think only Derived can check it. :( – Melkon Nov 20 '15 at 07:22

0 Answers0