On Wednesday, 11 May 2022 at 20:53:21 UTC, Marvin Hannott wrote:
On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote:
On 5/11/22 13:06, Marvin Hannott wrote:
> I appreciate the answer, don't much like the "solutions".
Me neither. :)
> It's not so much about copying
Great!
> scoped class objects should have value semantics.
std.typecons.scoped does exactly that:
https://dlang.org/phobos/std_typecons.html#scoped
import std.stdio;
import std.typecons;
interface Animal {
string sing();
}
class Cat : Animal {
this() {
writeln("Hi!");
}
~this() {
writeln("Bye!");
}
string sing() {
return "mew";
}
}
void foo(Animal animal) {
writeln(animal.sing());
}
void bar() {
auto cat = scoped!Cat();
foo(cat);
}
void main() {
bar();
}
The output:
Hi!
mew
Bye!
Ali
Yeah, but you can't return `Cat` 😉. And the documentation for
`scoped` says:
It's illegal to move a class instance even if you are sure
there are no pointers to it. As such, it is illegal to move a
scoped object.
That's kinda very limiting.
Anyway, I cooked up another idea based on your first
suggestions.
```D
struct S
{
static private interface I
{
int f(int i);
}
static private final class A : I
{
int f(int i) {return i;}
}
static private final class B : I
{
int f(int i) {return i+ 1;}
}
private I i;
private int d;
this(int d)
{
this.d = d;
if(d < 10)
{
i = scoped!A();
}else {
i = scoped!B();
}
}
int f() { return i.f(d);}
}
```
I mean, this is a super dumb example, but it kinda works. And I
think it could be made a lot less tedious with some mixin magic.
`scoped` is not necesary, try this:
```d
import std.typecons;
struct S{
static private interface I{
int f(int i)const;
}
static private final class A : I{
static immutable typeof(this) instance = new
immutable typeof(this)();
int f(int i)const {return i;}
}
static private final class B : I{
static immutable typeof(this) instance = new
immutable typeof(this)();
int f(int i)const {return i+ 1;}
}
private immutable I i;
private int d;
this(int d){
this.d = d;
if(d < 10) i = A.instance;
else i = B.instance;
}
int f() { return i.f(d);}
}
void main(){
import std.stdio;
S(1).f().writeln(); /// 1
S(100).f().writeln(); /// 101
}
```