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 == "*");
};

Reply via email to