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?
Re: normal function and template function conflict
On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra monarchdo...@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
Re: normal function and template function conflict
On Thursday, 26 July 2012 at 17:57:31 UTC, Simen Kjaeraas wrote: On Thu, 26 Jul 2012 19:18:21 +0200, monarch_dodra monarchdo...@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 :)
Re: normal function and template function conflict
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 monarchdo...@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
Re: normal function and template function conflict
On Thu, 26 Jul 2012 20:14:10 +0200, monarch_dodra monarchdo...@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 monarchdo...@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
Re: normal function and template function conflict
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.
Re: normal function and template function conflict
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
Re: normal function and template function conflict
On 7/26/12, Jacob Carlborg d...@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. :)
Re: normal function and template function conflict
On Thursday, July 26, 2012 21:49:35 Andrej Mitrovic wrote: On 7/26/12, Jacob Carlborg d...@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