View mode: basic / threaded / horizontal-split · Log in · Help
November 26, 2012
Help!
template isThing( alias symbol, A )
{
 enum isThing = false;
}

This template works in most contexts:

int x;
struct S {}

pragma(msg, isThing!x);
pragma(msg, isThing!S);

But this fails:
pragma(msg, isThing!int);

Why does it fail on a basic type (int), but not a user defined type (S)?
How can I fix the template declaration to not error in that case?
I tried:

template isThing( alias symbol, A )
{
 enum isThing = false;
}
template isThing( T, A )
{
 enum isThing = false;
}

Hoping the T version would catch the int, but this leads to different
errors "matches more than one template declaration".
November 26, 2012
Re: Help!
On Monday, 26 November 2012 at 16:37:08 UTC, Manu wrote:
> Why does it fail on a basic type (int), but not a user defined 
> type (S)?

S is a D symbol name, int isn't...

> How can I fix the template declaration to not error in that 
> case?

Try using only the (T,A) version, removing the alias version.

You might have to pass typeof(var) to it in some cases, but if 
you pass it typenames it should just work.
November 26, 2012
Re: Help!
> How can I fix the template declaration to not error in that 
> case?

If you want to have a template parameter that can be anything, 
including a a symbol or a built in type, you can use this ugly 
workaround:

template foo(bar...) if(bar.length == 1)
{
    enum foo = 1;
}
November 26, 2012
Re: Help!
On 26 November 2012 18:40, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Monday, 26 November 2012 at 16:37:08 UTC, Manu wrote:
>
>> Why does it fail on a basic type (int), but not a user defined type (S)?
>>
>
> S is a D symbol name, int isn't...
>
>
>  How can I fix the template declaration to not error in that case?
>>
>
> Try using only the (T,A) version, removing the alias version.
>
> You might have to pass typeof(var) to it in some cases, but if you pass it
> typenames it should just work.
>

The template works on symbol aliases, so I can't do that. It needs to
gracefully handle being given an int though somehow.
November 26, 2012
Re: Help!
On 26 November 2012 18:49, jerro <a@a.com> wrote:

> How can I fix the template declaration to not error in that case?
>>
>
> If you want to have a template parameter that can be anything, including a
> a symbol or a built in type, you can use this ugly workaround:
>
> template foo(bar...) if(bar.length == 1)
> {
>     enum foo = 1;
> }
>

Ahhhhh, that explains why 90% of std.traits is written in that super-weird
way! I always wondered what that was all about.

When you say 'anything' though, does that include alias parameters? Will
bar[0] be the equivalent of template foo(alias bar) if called with a symbol?
November 26, 2012
Re: Help!
On Monday, 26 November 2012 at 17:06:14 UTC, Manu wrote:
> When you say 'anything' though, does that include alias 
> parameters? Will
> bar[0] be the equivalent of template foo(alias bar) if called 
> with a symbol?

Yes.

D's inbuilt tuples can have both "expressions" and types. Tuples 
with only the former are called expression tuples. Tuples with 
only the latter are called type tuples (which is why people 
complain about the name of std.typecons.TypeTuple - it doesn't 
just take types).
November 26, 2012
Re: Help!
On 26 November 2012 19:06, Manu <turkeyman@gmail.com> wrote:

> On 26 November 2012 18:49, jerro <a@a.com> wrote:
>
>>  How can I fix the template declaration to not error in that case?
>>>
>>
>> If you want to have a template parameter that can be anything, including
>> a a symbol or a built in type, you can use this ugly workaround:
>>
>> template foo(bar...) if(bar.length == 1)
>> {
>>     enum foo = 1;
>> }
>>
>
> Ahhhhh, that explains why 90% of std.traits is written in that super-weird
> way! I always wondered what that was all about.
>
> When you say 'anything' though, does that include alias parameters? Will
> bar[0] be the equivalent of template foo(alias bar) if called with a symbol?
>

Ummm, immediate problem. That interferes with my argument list, inhibits
consecutive parameters. You'll notice my template had 'A' on the end... it
would make for a horrible API if the second arg were to come first in this
case... is that the only option?
November 26, 2012
Re: Help!
26.11.2012 20:36, Manu пишет:
> template isThing( alias symbol, A )
> {
>    enum isThing = false;
> }
>
> This template works in most contexts:
>
> int x;
> struct S {}
>
> pragma(msg, isThing!x);
> pragma(msg, isThing!S);
>
> But this fails:
> pragma(msg, isThing!int);
>
> Why does it fail on a basic type (int), but not a user defined type (S)?
> How can I fix the template declaration to not error in that case?
> I tried:
>
> template isThing( alias symbol, A )
> {
>    enum isThing = false;
> }
> template isThing( T, A )
> {
>    enum isThing = false;
> }
>
> Hoping the T version would catch the int, but this leads to different
> errors "matches more than one template declaration".

First, your `isThing` requires 2 parameters so all examples will fail to 
compile. Probably you meant `isThing(alias symbol)`.

Second, build-in type isn't a valid template alias parameter (probably 
as it isn't a "symbol"), see docs:
http://dlang.org/template.html#TemplateAliasParameter

Third, a workaround is to use template tuple parameter (as already 
suggested in this thread).

-- 
Денис В. Шеломовский
Denis V. Shelomovskij
November 26, 2012
Re: Help!
26.11.2012 21:11, Manu пишет:
> Ummm, immediate problem. That interferes with my argument list, inhibits
> consecutive parameters. You'll notice my template had 'A' on the end...
> it would make for a horrible API if the second arg were to come first in
> this case... is that the only option?

Yes it is the only option. And it isn't really a big problem.


-- 
Денис В. Шеломовский
Denis V. Shelomovskij
November 26, 2012
Re: Help!
On 26 November 2012 19:14, Denis Shelomovskij
<verylonglogin.reg@gmail.com>wrote:

> 26.11.2012 21:11, Manu пишет:
>
>  Ummm, immediate problem. That interferes with my argument list, inhibits
>> consecutive parameters. You'll notice my template had 'A' on the end...
>> it would make for a horrible API if the second arg were to come first in
>> this case... is that the only option?
>>
>
> Yes it is the only option. And it isn't really a big problem.


It's a public user-facing API. It's not a small problem, but it is
workable...
However, going with that, the supplementary question is, how do I then
discover if bar[0] is a symbol or not? I can't see any traits to test for
builtin types...
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home