Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
July 26, 2012 normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
I was trying to write a PRNG, and I wanted to give it two seed methods. The first is to seed from a unique UIntType, and the other is to seed from an entire range of seeds. Like so: -------- void seed(UIntType value = default_seed) {...} void seed(Range)(Range range) if (isInputRange!Range) {...} -------- Where UIntType is a template parameter of the struct. However, this makes the compiler complain, because of a conflict...? Is mixing normal functions with parametrized ones impossible? I *fixed* the issue by contemplating the first call with: -------- void seed(T)(T value = default_seed) if (is(typeof(T == UIntType))) {...} -------- Problems: 1) It is ugly as sin. 2) The default parameter doesn't work anymore. So here are my two questions: 1) Is what I was originally trying to do actually illegal, or is it some sort of compiler limitation? TDPL implies this should work perfectly fine... 2) Is there a "correct" workaround? |
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra <monarchdodra@gmail.com> wrote: > So here are my two questions: > 1) Is what I was originally trying to do actually illegal, or is it some sort of compiler limitation? TDPL implies this should work perfectly fine... Compiler limitation. It's supposed to work. > 2) Is there a "correct" workaround? Exactly what you did. Though, for brevity, you would write this: void seed(T : UIntType)(T value = default_seed) -- Simen |
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote:
> On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra <monarchdodra@gmail.com> wrote:
>> 2) Is there a "correct" workaround?
>
> Exactly what you did. Though, for brevity, you would write this:
>
> void seed(T : UIntType)(T value = default_seed)
Thanks
I haven't seen this construct before. Can you tell me a bit more
about it, or link me to some documentation about it?
I suppose it means "T must be UIntType", but I'd enjoy having a broader understanding of it :)
|
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 07/26/2012 11:14 AM, monarch_dodra wrote: > On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote: >> On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra >> <monarchdodra@gmail.com> wrote: >>> 2) Is there a "correct" workaround? >> >> Exactly what you did. Though, for brevity, you would write this: >> >> void seed(T : UIntType)(T value = default_seed) > > Thanks > > I haven't seen this construct before. Can you tell me a bit more > about it, or link me to some documentation about it? > > I suppose it means "T must be UIntType", but I'd enjoy having a broader > understanding of it :) Search for "specialization" in the following resources: http://dlang.org/template.html https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf http://ddili.org/ders/d.en/templates.html Ali |
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thu, 26 Jul 2012 20:14:10 +0200, monarch_dodra <monarchdodra@gmail.com> wrote: > On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote: >> On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra <monarchdodra@gmail.com> wrote: >>> 2) Is there a "correct" workaround? >> >> Exactly what you did. Though, for brevity, you would write this: >> >> void seed(T : UIntType)(T value = default_seed) > > Thanks > > I haven't seen this construct before. Can you tell me a bit more > about it, or link me to some documentation about it? > > I suppose it means "T must be UIntType", but I'd enjoy having a broader understanding of it :) Ali gave the general, I'll give the specifics. is(T : Foo), void bar(T : Foo)(T t), and a few others (not really others, they're exactly the same!) means 'T is implicitly convertible to Foo'. What's the difference, you ask? Consider: void foo(T)(T value) if (is(T == uint)) {} Could you call this function like this: foo(3); The answer is no. The compiler translates this to: foo!(typeof(3))(3); And typeof(3) is not uint, it's int. In contrast, void foo(T : uint)(T value) {} foo(3); is also translated to foo!(typeof(3))(3); and the compiler then checks if int is implicitly convertible to uint. And so it is, so the compiler moves happily onwards. There is a reason I included is(T : Foo) in the beginning, for you can write the exact same constraint like this: void foo(T)(T value) if (is(T : uint)) {} and it will compile just the same. For more information on this construct, I would, in addition to the links Ali provided, recommend you read this: http://dlang.org/expression.html#IsExpression IsExpressions are, however, probably the most hairy part of D, and their understanding has proven troublesome to many (myself included, though I believe I have grasped them now). Hence, most of their functionality is wrapped in more easily understandable templates in std.traits. -- Simen |
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Thursday, 26 July 2012 at 18:21:18 UTC, Ali Çehreli wrote:
> Search for "specialization" in the following resources:
Oh... "Specialization".
What with D's ability to conditionally implement, I had
completely forgotten about specialization. So that's how it's
done in D. Cool.
Thanks a lot.
|
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On 2012-07-26 19:57, Simen Kjaeraas wrote: >> 2) Is there a "correct" workaround? > > Exactly what you did. Though, for brevity, you would write this: > > void seed(T : UIntType)(T value = default_seed) Since a template function is actually not wanted this would be the correct workaround: void seed () (UIntType value = default_seed) Less typing as well. -- /Jacob Carlborg |
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 7/26/12, Jacob Carlborg <doob@me.com> wrote:
> void seed () (UIntType value = default_seed)
>
> Less typing as well.
Yep. It's funny how this works at all. I mean a template with no template parameters is somehow still a template. :)
|
July 26, 2012 Re: normal function and template function conflict | ||||
---|---|---|---|---|
| ||||
On Thursday, July 26, 2012 21:49:35 Andrej Mitrovic wrote:
> On 7/26/12, Jacob Carlborg <doob@me.com> wrote:
> > void seed () (UIntType value = default_seed)
> >
> > Less typing as well.
>
> Yep. It's funny how this works at all. I mean a template with no template parameters is somehow still a template. :)
It _is _ bit funny, but Ibelieve that it comes from permitting empty template parameter lists. Without that, recursion with eponymous templates would become problematic. e.g.
enum template myTemplate(T...)
{
static if(T.length == 0)
enum myTemplate = 42;
else
enum myTemplate = T[0] * 3 + myTemplate!(T[1 .. $]);
}
needs to be able to take an empty parameter list. It's probably possible to make that work without allowing an outright empty parameter list that isn't even a variadic template, but I suspect that it's just easier to allow it.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation