title: Multiple inheritance dilemma in C++
body: <p>I'm facing problems with the design of a C++ library of mine. It is a library for reading streams that support a feature I haven't found on other "stream" implementations. It is not really important why I've decided to start writing it. The point is I have a stream class that provides two important behaviours through multiple inheritance: shareability and seekability.</p>
  
  <p>Shareable streams are those that have a shareBlock(size_t length) method that returns a new stream that shares resources with its parent stream (e.g. using the same memory block used by parent stream). Seekable streams are those that are.. well, seekable. Through a method seek(), these classes can seek to a given point in the stream. Not all streams of the library are shareable and/or seekable.</p>
  
  <p>A stream class that both provides implementation for seeking and sharing resources inherits interface classes called Seekable and Shareable. That's all good if I know the type of such a stream, but, sometimes, I might want a function to accept as argument a stream that simply fulfills the quality of being seekable and shareable at the same time, regardless of which stream class it actually is. I could do that creating yet another class that inherits both Seekable and Shareable and taking a reference to that type, but then I would have to make my classes that are both seekable and shareable inherit from that class. If more "behavioural classes" like those were to be added, I would need to make several modifications everywhere in the code, soon leading to unmaintainable code. Is there a way to solve this dilemma? If not, then I'm absolutely coming to understand why people are not satisfied by multiple inheritance. It <em>almost</em> does the job, but, just then, it doesn't :D</p>
  
  <p>Any help is appreciated.</p>
  
  <p><strong>-- 2nd edit, preferred problem resolution --</strong></p>
  
  <p>At first I thought <a href="https://stackoverflow.com/users/161144/managu">Managu's</a> solution would be my preferred one. However, <a href="https://stackoverflow.com/users/147192/matthieu-m">Matthieu M.</a> came with another I preferred over Managu's: to use <code>boost::enable_if&lt;&gt;</code>. I would like to use Managu's solution if <code>BOOST_MPL_ASSERT</code> produced messages weren't so creepy. If there was any way to create instructive compile-time error messages, I would surely do that way. But, as I said, the methods available produce creepy messages. So I prefer the (much) lesser instructive, yet cleaner message produced when <code>boost::enable_if&lt;&gt;</code> conditions are not met.</p>
  
  <p>I've created some macros to ease the task to write template functions that take arguments inheriting select class types, here they go:</p>
  
  <pre><code>// SonettoEnableIfDerivedMacros.h
  #ifndef SONETTO_ENABLEIFDERIVEDMACROS_H
  #define SONETTO_ENABLEIFDERIVEDMACROS_H
  
  #include &lt;boost/preprocessor/repetition/repeat.hpp&gt;
  #include &lt;boost/preprocessor/array/elem.hpp&gt;
  #include &lt;boost/mpl/bool.hpp&gt;
  #include &lt;boost/mpl/and.hpp&gt;
  #include &lt;boost/type_traits/is_base_and_derived.hpp&gt;
  #include &lt;boost/utility/enable_if.hpp&gt;
  
  /*
      For each (TemplateArgument,DerivedClassType) preprocessor tuple,
      expand: `boost::is_base_and_derived&lt;DerivedClassType,TemplateArgument&gt;,'
  */
  #define SONETTO_ENABLE_IF_DERIVED_EXPAND_CONDITION(z,n,data) \
          boost::is_base_and_derived&lt;BOOST_PP_TUPLE_ELEM(2,1,BOOST_PP_ARRAY_ELEM(n,data)), \
                  BOOST_PP_TUPLE_ELEM(2,0,BOOST_PP_ARRAY_ELEM(n,data))&gt;,
  
  /*
      ReturnType: Return type of the function
      DerivationsArray: Boost.Preprocessor array containing tuples in the form
              (TemplateArgument,DerivedClassType) (see
                      SONETTO_ENABLE_IF_DERIVED_EXPAND_CONDITION)
  
      Expands:
      typename boost::enable_if&lt;
              boost::mpl::and_&lt;
                      boost::is_base_and_derived&lt;DerivedClassType,TemplateArgument&gt;,
                      ...
                      boost::mpl::bool_&lt;true&gt; // Used to nullify trailing comma
              &gt;, ReturnType&gt;::type
  */
  #define SONETTO_ENABLE_IF_DERIVED(ReturnType,DerivationsArray) \
          typename boost::enable_if&lt; \
                  boost::mpl::and_&lt; \
                          BOOST_PP_REPEAT(BOOST_PP_ARRAY_SIZE(DerivationsArray), \
                              SONETTO_ENABLE_IF_DERIVED_EXPAND_CONDITION,DerivationsArray) \
                          boost::mpl::bool_&lt;true&gt; \
              &gt;, ReturnType&gt;::type
  
  #endif
  
  // main.cpp: Usage example
  #include &lt;iostream&gt;
  #include "SonettoEnableIfDerivedMacros.h"
  
  class BehaviourA
  {
  public:
      void behaveLikeA() const { std::cout &lt;&lt; "behaveLikeA()\n"; }
  };
  
  class BehaviourB
  {
  public:
      void behaveLikeB() const { std::cout &lt;&lt; "behaveLikeB()\n"; }
  };
  
  class BehaviourC
  {
  public:
      void behaveLikeC() const { std::cout &lt;&lt; "behaveLikeC()\n"; }
  };
  
  class CompoundBehaviourAB : public BehaviourA, public BehaviourB {};
  class CompoundBehaviourAC : public BehaviourA, public BehaviourC {};
  class SingleBehaviourA : public BehaviourA {};
  
  template &lt;class MustBeAB&gt;
  SONETTO_ENABLE_IF_DERIVED(void,(2,((MustBeAB,BehaviourA),(MustBeAB,BehaviourB))))
  myFunction(MustBeAB &amp;ab)
  {
      ab.behaveLikeA();
      ab.behaveLikeB();
  }
  
  int main()
  {
      CompoundBehaviourAB ab;
      CompoundBehaviourAC ac;
      SingleBehaviourA    a;
  
      myFunction(ab); // Ok, prints `behaveLikeA()' and `behaveLikeB()'
      myFunction(ac); // Fails with `error: no matching function for
                      // call to `myFunction(CompoundBehaviourAC&amp;)''
      myFunction(a);  // Fails with `error: no matching function for
                      // call to `myFunction(SingleBehaviourA&amp;)''
  }
  </code></pre>
  
  <p>As you can see, the error messages are <em>exceptionally</em> clean (at least in GCC 3.4.5). But they can be misleading. It doesn't inform you that you've passed the wrong argument type. It informs you that the function <em>doesn't exist</em> (and, in fact, it doesn't due to SFINAE; but that may not be exactly clear to the user). Still, I prefer those clean messages over those <code>randomStuff ... ************** garbage **************</code> <code>BOOST_MPL_ASSERT</code> produces.</p>
  
  <p>If you find any bugs in this code, please edit and correct them, or post a comment in that regard. The one major issue I find in those macros is that they're limited to some Boost.Preprocessor limits. Here, for example, I can only pass a <code>DerivationsArray</code> of up to 4 items to <code>SONETTO_ENABLE_IF_DERIVED()</code>. I think those limits are configurable though, and maybe they will even be lifted in upcoming C++1x standard, won't they? Please, correct me if I'm wrong. I don't remember if they have suggested changes to the preprocessor.</p>
  
  <p>Thank you.</p>