Note that there are some explanatory texts on larger screens.

plurals
  1. POChaining operator= for write-only objects - OK to return rhs instead of *this?
    primarykey
    data
    text
    <p>It's well known that <code>operator=</code> should return a <strike>const</strike> reference to <code>*this</code> to support chaining, but this only works if <code>*this</code> <strike>can be used as an rvalue</strike> is value-like.</p> <p><strong>Edit:</strong> Fine, <code>operator=</code> should return a non-const reference (do as the <code>int</code>s), and I meant that <code>*this</code> needs to be a meaningful <code>rhs</code> in an assignment.</p> <p>I'm wrapping a C API of name=value setter functions through a C++ class <code>ApiWrapper</code> with <code>operator[]</code> returning a temporary write-only <code>Proxy</code> with overloaded <code>operator=</code>, but the API has no getter functions so <code>Proxy</code> is effectively write-only.</p> <pre class="lang-c++ prettyprint-override"><code>ApiWrapper x; x["a"] = x["b"] = 42; // x["b"] = 42; fine: consumes 42, returns *this // x["a"] = x["b"]; error: x["b"] does not have the value </code></pre> <p>It seems to me that if I return a const reference to <code>rhs</code> instead of <code>*this</code> from <code>operator=</code>, chaining would work fine. Conceptually (proxy boilerplate code left out):</p> <pre class="lang-c++ prettyprint-override"><code>struct Proxy { template &lt;typename T&gt; T const&amp; operator=(T const&amp; rhs) const { ... // pass rhs to the API but don't store it return rhs; // return rhs, not *this } }; ApiWrapper x; x["a"] = x["b"] = 42; // x["b"] = 42; fine: consumes and returns 42 // x["a"] = 42; fine: consumes and returns 42 </code></pre> <p>This makes me suspicious though. Are there any weird side effects from returning a const reference to <code>rhs</code> instead of <code>*this</code>? The only thing I can think of is that I won't be able to use it in expressions like <code>(x["a"] = 42).doSomething()</code> but my <code>Proxy</code> cannot support anything like that anyway, since it is write-only. Or would it be better to just disallow chaining (e.g. by returning <code>void</code>)?</p> <p><strong>Edit:</strong> Even if <code>Proxy</code> is not value-like, I think supporting assignment makes sense, it allows syntactic sugar like:</p> <pre class="lang-c++ prettyprint-override"><code>// this: // rather than: ApiWrapper w; API * ptr = make_api_instance(); w["name"] = "Batman"; api_set_str(ptr, "name", "Batman"); w["age"] = 42; api_set_int(ptr, "age", 42); w["pi"] = 3.14; api_set_double(ptr, "pi", 3.14); </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.
 

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