Trying to do alias template deduction myself.
Elfstone
elfstone at yeah.net
Fri Mar 31 05:19:48 UTC 2023
Related thread:
https://forum.dlang.org/thread/wgvtwckvjyhnbpcuyyqy@forum.dlang.org
It seems `dtemplate.deduceType` does all the deduction for both
`is` and IFTI. I can already add a better error message, right
before "goto Lnomatch":
`cannot deduce the instantiation of an alias template` (is that
the right term?)
This will better explain to new users why it really fails:
`NOT because no callable candidate exists, but because D never
tried to do anything about an alias template to find the match.
So try instantiating the function explicitly then it will work.`
But my goal is:
```D
struct Matrix(U, size_t M, size_t N)
{
U[M * N] data;
}
alias Vector3(U) = Matrix!(U, 3, 1);
alias Vec3(U) = Vector3!U;
alias Vec3Alt = Vector3;
alias Vec3Var(U...) = Vector3!(U);
alias V3(U) = Vector3!U;
alias Identity(U) = int;
void foo1(U)(in Vector3!U a)
{
}
void foo2(U)(in Vec3!U v)
{
}
void foo2Alt(U)(in Vec3Alt!U v)
{
}
void foo3Var(U...)(Vec3Var!(U))
{
}
void foo3(U)(in V3!U)
{
}
void foo4(U)(Identity!U u)
{
}
void main()
{
auto instVar = Vector3!float();
// The current behaviour is: deduction for alias template
will always fail.
// foo1(instVar); // expect OK
// foo2(instVar); // expect OK
// foo2Alt(instVar); // expect OK
// foo3Var(instVar); // expect OK
// foo3(instVar); // expect OK
// foo4(Identity!int()); // let it fail
// import std.regex;
// import std.traits;
// static assert(isInstanceOf!(Regex, Regex!char)); // now
fails, not sure it can be fixed along
}
```
How I like it to behave is based on what C++ offers.
```C++
template <typename T, size_t M, size_t N>
struct Matrix {
T data[M * N];
};
template<typename T, size_t M, size_t N>
using Mat = Matrix<T, M, N>;
template <typename T>
using Vector3 = Matrix<T, 3, 1>;
template <typename T>
using Vec3 = Vector3<T>;
template <typename T>
using Identity = int;
template <typename T>
void foo1(const Vector3<T>& v) {
}
template <typename T>
void foo2(const Vec3<T>& v) {
}
template <typename T, size_t M, size_t N>
void foo3(const Mat<T, M, N>& v) {
}
template <typename T>
void foo4(const Identity<T> id) {
}
int main() {
foo1(Vector3<float>()); // OK
foo2(Vector3<float>()); // OK
foo3(Vector3<float>()); // OK
// Let it fail
// foo4(Identity<int>()); // no matching overloaded function
found.
}
```
My current idea is to "expand" the alias with its to-be-matched
parameter(s) to the fullest form if possible (for example, V3!U >
Vec3!U > Matrix!(U, 3, 1)), then go to the parameter matching
routine.
It seems possible, if I just follow
`TemplateDeclaration.onemember` and expand the expression level
by level, give up when running into overloads, conditions, or
anything too complicate (I'm not sure if `onemember` ensures no
conditions). I could be wrong, but based on my few hours of
reading the code and really helpful comments in the forum, I
believe people who are more familiar with the compiler code can
implement it instantantly.
I'm making this post not to promise to fix it (I'll try), but to
gather opinions:
Do you think such behaviour in D is desirable (regardless of how
I imagine it can be implemented)?
What do I miss?
More information about the Digitalmars-d
mailing list