Const ref and rvalues again...
martin
kinke at libero.it
Wed Nov 7 07:01:24 PST 2012
On Wednesday, 7 November 2012 at 10:33:03 UTC, Timon Gehr wrote:
> You are still missing that const in C++ is different from const
> in D.
> const in C++ does not mean anything. It is just loosely
> enforced interface documentation. const in D actually restricts
> what the callee can do with the argument, in a transitive
> fashion.
I still don't get the big difference (except for transitiveness
for pointers). Given a const reference, I'm only able to invoke
methods decorated with the const keyword (or inout in D) keyword,
both in C++ and D. And I can only pass it as argument by ref to
functions which do not alter it (also taking a const reference,
that is).
> Also, if the point is to have higher speed, why shouldn't the
> function be allowed to use an rvalue as scratch space without a
> _deep copy_ ?
I'm sorry but I don't get what you mean here. Could you please
elaborate on this?
> When my struct does not support any operations that are const,
> and creating a mutable copy is not possible due to indirections?
If your struct doesn't support any const operations, it most
likely has good reasons not to.
> The change may well be visible...
True in this case, but only if you know exactly what foo() does
when you call it inside the main() function. And that is probably
an indicator for bad encapsulation - most of the time, you
shouldn't have the knowledge how foo() is exactly implemented
when using it from the outside.
It is clear that there are some examples where you want to pass
an rvalue argument to a mutable ref parameter if you know exactly
what the function does. But imo these cases are very rare and I
don't really regard it as big issue if you need to add a line
'auto tmp = myRvalue;' before the function call to transform it
to a referenceable lvalue, in these few cases.
Much more commonly, you need a parameter just as read-only input.
Consider a real-word-example of a 4x4 matrix consisting of 16
doubles (128 bytes). Most of the time, you'd only need a
read-only input instance when working with it (combining
matrices, transforming vectors etc.). Given its size (it's not
really huge, I acknowledge that ;)), you probably want to avoid
copying it around and therefore pass it by ref, but want that to
also work for rvalues (produced by matrix combinations like
'viewMatrix * modelMatrix', for example).
struct Matrix
{
double[16] data;
// this op= other
ref Matrix opOpAssign(string op)(in ref Matrix other);
// Matrix result = this op other
Matrix opBinary(string op)(in ref Matrix other) const;
// double4 result = this * vector
// the vector (32 bytes) may be passed by value for AVX
double4 opBinary(string op)(in ref double4 vector) const
if (op == "*");
};
More information about the Digitalmars-d
mailing list