Something like ADL from C++?

Max Samukha maxsamukha at gmail.com
Tue Dec 3 15:17:47 UTC 2024


On Tuesday, 3 December 2024 at 11:55:50 UTC, Manu wrote:

> Re-importing the globals into the same scope doesn't cause them 
> to combine either; just the symbol from whichever import 
> statement appears first is the winner...
>
> Has anyone ever experimented with a pattern like this? 
> Essentially, I can't work out how to expand /combine an 
> overload set to include symbols from multiple imports....

You could merge overloads like this:

```
module a;

struct A
{
}

void serialise(void[], A)
{
     import std.stdio;
     writeln("A.serialize");
}

---
module b;

struct B
{
}

void serialise(void[], B)
{
     import std.stdio;
     writeln("B.serialise");
}

---
module default_serialise;

void serialise(T)(void[], T t)
{
     import std.stdio;
     writeln("T.serialise");
}

---
module main;

enum isUserType(T) = true; // change to whatever

// this is needed because we still cannot express "local to 
static foreach".
template serialiseOf(T)
{
     static if (is(__traits(parent, T) == module) && isUserType!T)
     {
         alias mod = __traits(parent, T);
         alias serialiseOf = mod.serialise;
     }
     else
     {
         static import default_serialise;
         alias serialiseOf = default_serialise.serialise;
     }
}

// this is needed because D doesn't allow overloading local 
functions.
template doSerialiseImpl(Things...)
{
     static foreach(Thing; Things)
         alias doSerialiseImpl = serialiseOf!Thing;
}

void doSerialise(Things...)(void[] buffer, Things things)
{
     static foreach (thing; things)
         doSerialiseImpl!Things(buffer, thing);
}

void main()
{
     import a, b;
     doSerialise(null, A(), B(), 42);
}
```

It never ceases to amaze me how difficult it still is to make 
such trivial things work.


More information about the Digitalmars-d mailing list