On Wednesday, 23 December 2020 at 20:56:26 UTC, jmh530 wrote:
On Wednesday, 23 December 2020 at 16:25:58 UTC, 9il wrote:
[snip]
1.
Alias template function parameter resolution
https://github.com/dlang/dmd/pull/9778
[snip]
I gave some thought to potential alternatives, but this is
really the simplest way to think about it.
For instance, I would imagine that something like below would
be expected to compile if this is ever resolved.
struct Foo(T) {}
alias Bar(T) = Foo!T;
void f(T)(Foo!T x) {}
void b(T)(Bar!T x) {}
void main() {
auto foo = Foo!int();
auto bar = Bar!int();
foo.f;
foo.b;
bar.f;
bar.b;
}
If you instead use template constraints, then you have to rely
on helper functions for anything more complicated and you are
no longer following DRY. For instance, a function like
enum bool isBar(T) = is(T == Foo!U, U);
void fb(T)(T x) if(isBar!T) {}
will compile (adjusting the calls above), but you are repeating
Foo!U.
Because of the bugs mentioned in other posts, replacing isBar
with below will not.
enum bool isBar(T) = is(T == Bar!U, U);
Given the similarities between template constraints and
concepts, something like below could accomplish something
similar
concept Bar(T) = is(T == Foo!U, U);
but that doesn't help you if you want to also be able to use
the template alias, as in
auto bar = Bar!int();
This is because Bar(T) in the concept should be passing a
Foo!T. You would still need to have the alias for Bar if you
want that functionality (and how to name them when they are
doing similar things). Abusing C++'s syntax you might have
something like
concept Bar(T) = requires(U)() {
Foo!U; //akin to something like typename T::Foo<U>;
}
where we would basically be telling the compiler that T has to
be a Foo!U, which would mean you would have to use Bar like
Bar!U...at least that's the idea. I don't think anything like
this would work currently in C++.
I don't have time to dig into what you are trying to do, but
you'll be surprised what can be done in C00... but I think the
original point is that your example unifies fine with C++ :
template<class T>
struct Foo {
int f,b;
};
template<class T>
using Bar = Foo<T>;
template<class T>
void f(Foo<T> x) {};
template<class T>
void b(Bar<T> x) {}
int main() {
auto foo = Foo<int>();
auto bar = Bar<int>();
foo.f;
foo.b;
bar.f;
bar.b;
}