Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are two axises of variation in writing: the write0/write1 choice and the MsgA/B/C.... choice. </p> <p>Conceptually that means you need NxM implementations of a <code>write</code> function. Of course, if a write implementation is added, or a message type is added, this leads to resp. M or N extra functions to be added. </p> <p>For both axises you can choose whether to implement them using static or dynamic polymorphism. The static polymorphism can be done using templates or using function overrides.</p> <p>It could be done by creating a N element class hierarchy with M write functions in each class. But it would soon become a maintenance nightmare. Unless the message content is also runtime polymorphic. But the question is about static polymorphism for the messages.</p> <p>Since runtime polymorphism is ruled out because of too elaborate (and you can't have a template function virtual, which would decrease the verbosity of overrides), we need to implement a little type-dispatching routine, converting runtime information into compile-time information.</p> <p>More specifically: templatize the main action (in the example called <code>Tmain</code>) with the writer-to-use, and call it with the right template argument from the 'real' <code>main</code>.</p> <p>This omits the use of a 'global' choice variable, yet is object-oriented and concise.</p> <pre><code> // twodimensionalpolymorph.cpp // #include &lt;iostream&gt; using namespace std; class Write0 { public: template&lt; typename tMsg &gt; void operator()( /*const*/ tMsg&amp; msg ) { cout &lt;&lt; "write0: " &lt;&lt; msg.name() &lt;&lt; endl; }; }; class Write1 { public: template&lt; typename tMsg &gt; void operator()( /*const*/ tMsg&amp; msg ) { cout &lt;&lt; "write1: "&lt;&lt; msg.name() &lt;&lt; endl; }; }; struct MsgA { const char *name() { return "MsgA"; } }; struct MsgB { const char *name() { return "MsgB"; } }; struct MsgC { const char *name() { return "MsgC"; } }; struct MsgD { const char *name() { return "MsgD"; } }; // the Tmain does the real action // template&lt; typename Writer &gt; int Tmain( Writer&amp; write, int argc, char** args ) { write( MsgA() ); write( MsgB() ); write( MsgB() ); write( MsgD() ); return 0; } // the main merely chooses the writer to use // int main( int argc, char** args ) { if( argc==1 ) return Tmain( Write0(), argc, args); else return Tmain( Write1(), argc, args); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload