On Monday, 12 March 2018 at 13:04:54 UTC, Simen Kjærås wrote:
On Monday, 12 March 2018 at 10:37:00 UTC, Alex wrote:
Sure, you have.
https://dlang.org/spec/struct.html#assign-overload
Point #4.
In this case,
ref S opAssign(ref S rhs)
{
return this;
}
True. Can you fix these, too?
struct S {
S* ptr;
this(int dummy) {
ptr = &this;
}
~this() {
assert(ptr == &this);
}
}
void test(S s) {}
unittest {
test(S(0));
}
S test2() {
return S(0);
}
unittest {
S s = test2();
}
ok... this is a little bit more tricky, as there is no assignment
now. :)
But in this two cases I assume, you want to have explicit pass by
reference, no?
struct S {
S* ptr;
this(int dummy) {
ptr = &this;
}
~this() {
assert(ptr == &this);
}
}
void test(ref S s){}
unittest {
auto s = S(0);
test(s);
/*
if I call test(S(0)) with void test(S s) as in your example,
neither the postblit nor opAssign is called... hm... no idea
why...
*/
}
auto test2() {
return new S(0);
}
unittest {
auto s = test2();
/*
This example differs more from the post before :) test2 is a
true factory now,
it has to grant the right setting of all members...
*/
}
Another point is, that I hope, that pointers don't move
anywhere, as in C, by definition.
And why not? D allows for moving garbage collectors.
If it were allowed, then "contiguous memory allocation" for
arrays would be senseless.
unittest {
auto tmp = typeof(S.a)();
}
I thought, this shouldn't be possible (at least in my mind)
It wouldn't, and such code is not possible in D today:
struct S {
int n;
auto a() { return SomeType!(() => n)(); }
}
struct SomeType(alias fn) {
int get() { return fn(); }
}
But this is clearly valid.
Yes, it's an example of code that works in D today, with
similar semantics to those implied in the other example. It's
meant to show that just like `auto tmp = typeof(S.a())()`
doesn't work today, it shouldn't work with the types used in my
other example.
unittest {
// cannot access frame pointer of
foo.S.a.SomeType!(delegate () => this.n).SomeType
auto tmp = typeof(S.a())();
}
For sure, tmp cannot be defined without an instance of S. So
the correct unittest in my eyes would be:
unittest {
S s;
auto res = s.a;
assert(res.get == S.init.n);
}
I think we may be speaking past one another. Yes, your unittest
would be expected to pass.
If we go back to the example code:
struct S1 {
int n, m;
SomeType!(() => n + m) a;
}
vs.
struct S2 {
int n, m;
auto a() { return SomeType!(() => n + m)(); }
}
I would expect typeof(S1.a) and typeof(S2.a()) to be
equivalent. I don't see a good reason why I should be able to
construct an instance of typeof(S1.a), since I can't construct
a typeof(S2.a()).
I see your point that "The latter closures above the current
values inside of [S2]". I'm saying I want the former to do the
same. I understand that it currently doesn't, and I argue that
having it do the same would be a much more useful behavior.
Apart from the fact it's impossible, I don't see any good
reason not to make it work. :p
I see your point too :)
But the latter form just grants the existence of an instance of
S, whereas the first form doesn't.
By the way, this would work:
struct S1 {
static int n, m; // added a static here.
SomeType!(() => n + m) a;
}
struct SomeType(alias fn){}
--
Simen