Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Your sample code contains many errors, including slicing problems.</p> <p>I'm not 100% sure, but I seem to remember you can use <code>const type_info*</code> as a key for a map. </p> <p>If so, you could use something like following. It is not free from RTTI (<code>type_info</code>), but since Evaluator already checks the typeids, you can use a <code>static_cast</code> instead of a <code>dynamic_cast</code> (but it isn't that important now that the code doesn't blindly search for the right operator to apply).</p> <p>Of course, the following is completely broken in terms of memory management. Reimplement with smart pointers of your choice.</p> <pre><code>#include &lt;map&gt; #include &lt;typeinfo&gt; #include &lt;cassert&gt; #include &lt;iostream&gt; struct CompareTypeinfo { bool operator()(const std::type_info* a, const std::type_info* b) const { return a-&gt;before(*b); } }; class Var { public: virtual ~Var() {} virtual const std::type_info&amp; getType() const = 0; virtual void print() const = 0; }; template&lt;typename T&gt; class VarT : public Var { T value; public: VarT(const T&amp; v): value(v) {} const T&amp; getValue() const { return value; } virtual const std::type_info&amp; getType() const { return typeid(T); } virtual void print() const { std::cout &lt;&lt; value &lt;&lt; '\n'; } }; class Operator { public: virtual ~Operator() {} virtual Var* evaluate(const Var&amp; a, const Var&amp; b) const = 0; virtual const std::type_info&amp; getType() const = 0; }; template&lt;typename T&gt; class AddOperator : public Operator { public: typedef T type; virtual const std::type_info&amp; getType() const { return typeid(T); } virtual Var* evaluate(const Var&amp; a, const Var&amp; b) const { //it is the responsibility of Evaluator to make sure that the types match the operator const VarT&lt;T&gt;* varA = static_cast&lt;const VarT&lt;T&gt;*&gt;(&amp;a); const VarT&lt;T&gt;* varB = static_cast&lt;const VarT&lt;T&gt;*&gt;(&amp;b); return new VarT&lt;T&gt;(varA-&gt;getValue() + varB-&gt;getValue()); } }; class Evaluator { private: typedef std::map&lt;const std::type_info*, Operator*, CompareTypeinfo&gt; TypedOpMap; typedef std::map&lt;int, TypedOpMap&gt; OpMap; OpMap operatorMap; public: template &lt;class Op&gt; void registerOperator(int opId) { operatorMap[opId].insert(std::make_pair(&amp;typeid(typename Op::type), new Op)); } Var* evaluate(const Var&amp; a, const Var&amp; b,int opId) { OpMap::const_iterator op = operatorMap.find(opId); if (op != operatorMap.end() &amp;&amp; a.getType() == b.getType()) { TypedOpMap::const_iterator typed_op = op-&gt;second.find(&amp;a.getType()); if (typed_op != op-&gt;second.end()) { //double-checked assert(typed_op-&gt;second-&gt;getType() == a.getType()); return typed_op-&gt;second-&gt;evaluate(a, b); } } return 0; } }; int main() { Evaluator e; e.registerOperator&lt;AddOperator&lt;int&gt; &gt;(0); e.registerOperator&lt;AddOperator&lt;double&gt; &gt;(0); VarT&lt;int&gt; i1(10), i2(20); VarT&lt;double&gt; d1(2.5), d2(1.5); VarT&lt;float&gt; f1(1.0), f2(2.0); Var* i_result = e.evaluate(i1, i2, 0); Var* d_result = e.evaluate(d1, d2, 0); Var* f_result = e.evaluate(f1, f2, 0); Var* mixed_result = e.evaluate(i1, d2, 0); assert(i_result != 0); assert(d_result != 0); assert(f_result == 0); //addition not defined for floats in Evaluator assert(mixed_result == 0); //and never for mixed types i_result-&gt;print(); //30 d_result-&gt;print(); //4.0 } </code></pre>
    singulars
    1. This table or related slice is empty.
    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. VO
      singulars
      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