That's the solution I wanted to suggest. I proposed to pass the Ref<>
objects by value mostly because it looks better for writable
arguments. Having a "const Ref<VectorXf>&" writable is a bit
dangerous. But if we agree that copy-back is a no go, then the
internal m_object will exists only for const version so one could pass
by a const reference for const arguments, and by value for writable
ones.
Yes, sounds like a plan. This should cause no overhead if the m_object is
not required, just some temporary stack space.
Furthermore, this can then be used for (fixed size) aligned references as
well, copying the expression, iff it is not aligned at compile-time.
Since we are fine-tuning the expected behavior, I wonder whether we
should allow implicit evaluation for inputs having "direct-access".
Let's consider a function foo1 taking a "const Ref<const VectorXf>&"
as argument. It is expected that the following calls yield an
evaluation into a temporary:
foo1(a+b);
foo1(-a);
However, when the input argument references an object with storage, an
implicit evaluation might be surprising as in the following cases:
foo1(A.row(i));
foo1(b.imag());
If we forbid such cases, in practice this means the user will have to
explicitly call .eval() in such cases. This behavior would also be
coherent with the non-const version for which 1) the input argument
has by construction "direct-acces", and 2) we already stated that
implicit evaluation into a temp would be too risky.
On the other hand, if we do so, I already see users coming back to us
with statements as "foo(1*A.row(i)) compiles but foo(A.row()) does
not, wtf?". So I'm a bit puzzled here.