Bug 9864 – Allow instantiating eponymous inner template with a single parameter list
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-04-03T01:03:00Z
Last change time
2016-08-27T23:23:53Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2013-04-03T01:03:55Z
Here's a hasField template which allows you to instantiate it with only one parameter to create an alias:
-----
template hasField(string name)
{
template hasField(T)
{
enum bool hasField = __traits(hasMember, T, name);
}
}
struct S1 { int x; }
struct S2 { int y; }
void main()
{
alias hasX = hasField!"x";
static assert(hasX!S1);
static assert(!hasX!S2);
static assert(hasField!("x", S1)); // ng
}
-----
Unfortunately we cannot use this template directly. We can turn it into a normal template:
-----
template hasField(string name, T)
{
enum bool hasField = __traits(hasMember, T, name);
}
-----
But then we lose the ability to alias the template with a single type parameter:
-----
alias hasX = hasField!"x"; // ng
-----
There is a library workaround for this, by introducing a Curry template:
-----
template Curry(alias Templ, T...)
{
template Curry(X...)
{
alias Curry = Templ!(T, X);
}
}
template hasField(string name, T)
{
enum bool hasField = __traits(hasMember, T, name);
}
struct S1 { int x; }
struct S2 { int y; }
void main()
{
alias hasX = Curry!(hasField, "x"); // ok
static assert(hasX!S1);
static assert(!hasX!S2);
static assert(hasField!("x", S1)); // ok
}
-----
Nevertheless it would be nice to be able to use the first syntax as well.
I consider this a low priority enhancement since a library workaround exists.
Comment #1 by andrej.mitrovich — 2016-08-27T23:23:53Z
Needs to be a DIP, but also this would be a big change in language semantics. I don't really need it as much as I thought I did.