It's well known that operator=
should return a const reference to *this
to support chaining, but this only works if *this
can be used as an rvalue is value-like.
Edit: Fine, operator=
should return a non-const reference (do as the int
s), and I meant that *this
needs to be a meaningful rhs
in an assignment.
I'm wrapping a C API of name=value setter functions through a C++ class ApiWrapper
with operator[]
returning a temporary write-only Proxy
with overloaded operator=
, but the API has no getter functions so Proxy
is effectively write-only.
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
It seems to me that if I return a const reference to rhs
instead of *this
from operator=
, chaining would work fine. Conceptually (proxy boilerplate code left out):
struct Proxy {
template <typename T>
T const& operator=(T const& 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
This makes me suspicious though. Are there any weird side effects from returning a const reference to rhs
instead of *this
? The only thing I can think of is that I won't be able to use it in expressions like (x["a"] = 42).doSomething()
but my Proxy
cannot support anything like that anyway, since it is write-only. Or would it be better to just disallow chaining (e.g. by returning void
)?
Edit: Even if Proxy
is not value-like, I think supporting assignment makes sense, it allows syntactic sugar like:
// 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);