Note that there are some explanatory texts on larger screens.

plurals
  1. POC++: force the compiler to use one of two competing operators
    primarykey
    data
    text
    <p>I've been playing with C++ recently, and I just stumbled upon an interesting precedence issue. I have one class with two operators: "cast to double" and "+". Like so:</p> <pre><code>class Weight { double value_; public: explicit Weight(double value) : value_(value) {} operator double() const { return value_; } Weight operator+(const Weight&amp; other) { return Weight(value_ + other.value_); } }; </code></pre> <p>When I try to add two instances of this class...</p> <pre><code>class Weighted { Weight weight_; public: Weighted(const Weight&amp; weight) : weight_(weight) {} virtual Weighted twice() const { Weight w = weight_ + weight_; return Weighted(w); } }; </code></pre> <p>...something unexpected happens: the compiler sees the "+" sign and casts the two <code>weight_</code>s to <code>double</code>. It then spits out a compilation error, because it can't implicitly cast the resulting double back to a <code>Weight</code> object, due to my <code>explicit</code> one-argument constructor.</p> <p>The question: how can I tell the compiler to use my own <code>Weight::operator+</code> to add the two objects, and to ignore the cast operator for this expression? Preferably without calling <code>weight_.operator+(weight_)</code>, which defeats the purpose.</p> <hr> <p><strong>Update</strong>: Many thanks to chris for pointing out that the compiler is right not to use my class's <code>operator+</code> because that operator is not <code>const</code> and the objects that are being <code>+</code>ed are <code>const</code>.</p> <p>I now know of three ways to fix the above in VS2012. Do see the accepted answer from chris for additional information.</p> <ol> <li>Add the <code>explicit</code> qualifier to <code>Weight::operator double()</code>. This doesn't work in VS 2012 (no support), but it stands to reason that it's a good solution for compilers that do accept this approach (from the accepted answer).</li> <li>Remove the <code>virtual</code> qualifier from method <code>Weighted::twice</code>, but don't ask me why this works in VS.</li> <li>Add the <code>const</code> qualifier to method <code>Weight::operator+</code> (from the accepted answer).</li> </ol>
    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.
 

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