On Mon, Dec 14, 2015 at 3:16 PM, Agustín K-ballo Bergé < kaballo86@hotmail.com> wrote:
On 12/14/2015 7:57 PM, Emil Dotchevski wrote:
On Mon, Dec 14, 2015 at 1:12 PM, Agustín K-ballo Bergé < kaballo86@hotmail.com> wrote:
On 12/14/2015 5:53 PM, Emil Dotchevski wrote:
On Mon, Dec 14, 2015 at 4:46 AM, Agustín K-ballo Bergé <
if the compiler says there is an error here because `normalized` needs a
default constructor, I'm gonna start suspecting something wrong is going
on with the library. This is what I would naively expect `normalized` to be doing:
template <typename Vec> Vec normalized(Vec v) { return v /= length(v); }
It can't be implemented that way because the type of the argument might not be copyable.
Does this mean that the library explicitly supports movable-only types? That's somewhat unexpected, given that the library requires all type information necessary for embedded storage, but it's not a bad thing. It would be good to add this information to the reference documentation.
QVM is neutral wrt move semantics but views are non-copyable and non-movable because copy or move semantics would require a temporary object, which QVM views are carefully designed to avoid. You can assign to a view and it will convert to any compatible type, but you can't copy or move it. That's why you can chain views up with no overhead: any operation on a view or multiple chained views works with the original object, no other objects are created.
Views are special, that has already been established. My question was not in regard of views, whose case I said is unsurprising. My question was with respect to this simple guy requiring the presence of a default constructor:
myvec3 n = normalized(myvec3(1, 2, 3));
Why does this guy require a default constructor? Now you said the library cannot call a constructor other than the default one, which is not the case. So I wonder if you had experimented with this particular case, which does not conceptually require a default constructor, and for which the library is already calling another constructor, a copy/move constructor given the simple fact that it is being returned from a function.
Why does this guy require a default constructor? I understand now that it doesn't, you simply don't want to handle this case any different than you already do views. There's nothing wrong with that.
I'm not sure if we're on the same page. I'll try again. :) If you have struct myvec3 { .... }; then if you go: myvec3 v1 = ....; myvec3 v2=normalized(v1); It is indeed puzzling why would that need a default constructor. But consider this code: struct mymat3 { .... }; mymat3 m = ....; myvec3 v=normalized(col<1>(m)); //Take column 1 as vector In this case col<1> returns a reference to m, which is passed by reference to normalized. The use of col<1> created no temporary, but the flip side is that the reference it returns is of type that (by design) is neither copyable or movable. If instead you did: myvec3 v=normalized(col<1>(transp(m))); //Transpose, then take column 1 as vector transp returns a reference to m, which col<1> takes by reference and returns by reference, which is then passed by reference to normalized(), so again, no temporary is created in this sequence of calls. But in the end, normalized must return an object -- and it can't use a copy constructor (different types). And since I've never encountered a vector type without a default constructor, it seemed reasonable to not worry too much about requiring it. Emil