Note that there are some explanatory texts on larger screens.

plurals
  1. POCombining templates and inheritance in tree conversion
    text
    copied!<p>I have data stored in a C++ tree structure which I read in from a file. The tree looks like that:</p> <pre><code>class BaseNode { std::vector&lt;BaseNode*&gt; children_; ... }; class WhiteNode : public BaseNode { ... }; class BlackNode : public BaseNode { ... }; </code></pre> <p>After the tree is built, I would like to convert it, e.g. to a string.</p> <p>In order to keep the tree code separate from the conversion code, I would like to use templates, i.e. implementing something like that:</p> <pre><code>template &lt;class T&gt; T WhiteNode::Convert() { ... }; </code></pre> <p>However, since the tree nodes are stored as <code>BaseNode*</code>, I don't know how to access such a template member function. And since template member functions cannot be inherited, I don't think this will work.</p> <p>I did come up with a working solution, though:</p> <pre><code>class BaseConversion { public: virtual ~BaseConversion() {} virtual void * FromBlack() = 0; virtual void * FromWhite() = 0; }; template &lt;class T&gt; class Conversion : public BaseConversion { public: void * FromBlack(); void * FromWhite(); }; class BaseNode { std::vector&lt;BaseNode*&gt; children_; virtual void * Convert(BaseConversion * conversion) = 0; public: virtual ~BaseNode() {} template &lt;class T&gt; T Convert() { return *static_cast&lt;T*&gt;(Convert(new Conversion&lt;T&gt;)); } }; class WhiteNode : public BaseNode { void * Convert(BaseConversion * conversion) { return conversion-&gt;FromWhite(); } }; class BlackNode : public BaseNode { void * Convert(BaseConversion * conversion) { return conversion-&gt;FromBlack(); } }; </code></pre> <p>And the transformation logic can be entirely separate:</p> <pre><code>template &lt;&gt; void * Conversion&lt;std::string&gt;::FromWhite() { return new std::string("converting WHITE node to std::string ..."); } template &lt;&gt; void * Conversion&lt;std::string&gt;::FromBlack() { return new std::string("converting BLACK node to std::string ..."); } </code></pre> <p>Testing the code:</p> <pre><code>BaseNode * node = new BlackNode; std::cout &lt;&lt; node-&gt;Convert&lt;std::string&gt;() &lt;&lt; std::endl; node = new WhiteNode; std::cout &lt;&lt; node-&gt;Convert&lt;std::string&gt;() &lt;&lt; std::endl; </code></pre> <p>returns the expected result:</p> <pre><code>converting BLACK node to std::string ... converting WHITE node to std::string ... </code></pre> <p>Although this solution works, I am sure it can be done much easier. Any other, simpler solution I came up with failed, e.g. due to type erasure.</p> <p>I would appreciate any help on that. Thanks!</p>
 

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