Something like ADL from C++?
Arafel
er.krali at gmail.com
Fri Dec 6 09:46:55 UTC 2024
On 6/12/24 9:05, Richard (Rikki) Andrew Cattermole wrote:
> I'm fully aware of template this parameters, I was trying to get them to
> work 10 years ago.
>
> They have problems that prevent their usage.
>
> 1. They are templates, so not in vtable
> 2. They require the this pointer to be typed to the child (extremely
> easy for this to not be the case, see 1)
> 3. Because they are not virtual, you cannot up cast (see 2)
> 4. Cannot be over ridden for any manual behavior
>
> All and all, they become very complex for common usage, quite fragile if
> you don't use them right, not the kind of thing you recommend to people
> who are use to runtime reflection.
That's true, I found a workaround using constructors and registering
classes there, but currently it only works with one level of inheritance
(without user intervention, the whole purpose of it):
```d
import std;
class SerializationRoot {
static void function()[TypeInfo_Class] serializationMethods;
// We would need a `shared static` constructor that would be always
called
/* shared static */ this(this T)() {
auto myType = typeid(T);
if (myType !in serializationMethods) {
writeln("Registering type ", myType);
serializationMethods[myType] =
(&T.serializeDefaultImpl!T).funcptr;
}
}
void serialize() {
auto myType = typeid(this);
assert(myType in serializationMethods, "The class was not
registered for default serialization.");
void delegate() dlg;
dlg.funcptr = serializationMethods[myType];
dlg.ptr = cast (void *) this;
dlg();
stdout.flush;
}
void serializeDefaultImpl(T)() {
T realThis = cast(T) this;
writeln("Default serialization for ", typeid(realThis));
}
}
class MyClass : SerializationRoot { }
class MyOtherClass : SerializationRoot {
this(int) { }
override void serialize() {
writeln("This class does something special, but still uses the
default mechanism.");
super.serialize;
}
}
class MySpecialClass : SerializationRoot {
override void serialize() {
writeln("This class disregards everything takes everything into
its own hands.");
}
}
class MyProblematicClass : MyClass { }
void main() {
SerializationRoot myClass = new MyClass;
SerializationRoot myOtherClass = new MyOtherClass(1);
SerializationRoot mySpecialClass = new MySpecialClass();
SerializationRoot myProblematicClass = new MyProblematicClass();
myClass.serialize;
myOtherClass.serialize;
mySpecialClass.serialize;
myProblematicClass.serialize; // BOOM!
}
```
But it should work as expect if we had templated-this (shared) static
constructors. My reading is that they are actually not forbidden in the
spec ("member functions" should include static ones too) [1], and there
is already an open bug for that [2] (with some duplicates).
Unfortunately I don't think it'll happen anytime soon, and I don't have
the skills to have a go at it myself.
[1]: https://dlang.org/spec/template.html#template_this_parameter
[2]: https://issues.dlang.org/show_bug.cgi?id=10488
More information about the Digitalmars-d
mailing list