template alias args
Philippe Sigaud
philippe.sigaud at gmail.com
Mon May 21 13:46:20 PDT 2012
On Mon, May 21, 2012 at 5:20 PM, Manu <turkeyman at gmail.com> wrote:
> So I keep finding myself in a situation where I need to use an alias
> template arg, but what I actually want to alias is a MEMBER of some symbol,
> or even a function local.
>
> struct MyStruct
> {
> int x;
> }
>
> template Thing(alias t)
> {
> ...
> }
>
> MyStruct s;
>
> Thing!(s); // this is fine
> Thing!(s.x); // this doesn't work
>
> This seems like it should work intuitively, I was very surprised when it
> didn't. 's.x' can be resolved just as easily as 's' at compile time, but
> Walter said 'alias' could only understand absolute symbols, not symbol +
> offset.
> Has anyone else run into this? What's the reason for the restriction?
This works for me (DMD 2.059, Linux)
module test;
import std.stdio;
struct MyStruct
{
int x;
}
template Thing(alias t)
{
alias typeof(t) Thing; // just to use Thing
}
void main()
{
MyStruct s;
writeln(Thing!(s).stringof);
writeln(Thing!(s.x).stringof);
}
No error with Thing!(s.x) and the result is correct. What compiler are
you using?
> I've also found I need to do this on a number of occasions: template
> Thing(alias T...)
> Ie, receive an unknown number of aliases... But that doesn't work either.
Use 'T...' Template Parameters Tuples accept alias and types, mixed
as you wish.
If you want T... to accept only types and no aliases, you'll have to
use a template constraint, using std.traits.allSatisfy!(isType, T)
With (for example):
template isType(T)
{
enum isType = true;
}
template isType(alias a)
{
static if (is(a))
enum isType = true;
else
enum isType = false;
}
Note 1: user-defined types are *both* a type and a symbol (thus
alias-able). Cue floor wax and dessert topping.
Note 2: built-in types are... just types (wew!)
template isBuiltinType(T)
{
enum isBuiltinType = true;
}
template isBuiltinType(alias a)
{
enum isBuiltinType = false;
}
Note: If you have a template that makes sense for both an alias and a
type, and you don't want to repeat yourself, you can use a one-element
tuple:
template Thingy(T...) if (T.length == 1)
{
... Use T[0] here
}
More information about the Digitalmars-d
mailing list