How do I simulate variadic parameters for template (range) functions?

Steven Schveighoffer schveiguy at yahoo.com
Wed Aug 24 10:54:12 PDT 2011


On Wed, 24 Aug 2011 13:40:38 -0400, Andrej Mitrovic  
<andrej.mitrovich at gmail.com> wrote:

> Here's what I can do with a variadic function:
>
> void main()
> {
>     int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];
>
>     process(a[a.countUntil(7) .. $]);
>     process(1);
> }
>
> void process(int[] vals...)
> {
>     foreach (val; vals)
>     {
>     }
> }
>
> Very simple, pass one or multiple arguments. But then I thought about
> using the `until` template instead of countUntil. However `until`
> returns a range. So my next guess was to write:
>
> void main()
> {
>     int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];
>
>     process(a.until(7));  // ok
>     process(4);  // error since 4 is not a range
> }
>
> void process(Range)(Range vals) if (isInputRange!Range &&
> is(ElementType!Range == int))
> {
>     foreach (val; vals)
>     {
>     }
> }
>
> Is it somehow possible to automatically convert a literal to a range?
> I really miss the convenience of variadic functions. I thought about
> making an overload that only takes an int and constructing a simple
> input range around it so it can be passed to process(), e.g.:
>
> void process(Range)(Range vals) if (isInputRange!Range &&
> is(ElementType!Range == int))
> {
>     foreach (val; vals)
>     {
>     }
> }
>
> void process(int arg)
> {
>     process(makeInputRange(arg));  // make an input range, pass to
> above process()
> }
>
> But I can't overload templated and non-templated functions, I think
> this is one of those old-standing bugs.

maybe:

void process(Range)(Range vals) if (isInputRange!Range &&  
is(ElementType!Range == int))
{
    ...
}

void process(Vals...)(Vals vals) if (allValsElementsAreInt)
{
    ...
}

Note that I'm not sure what to put for allValsElementsAreInt...

-Steve


More information about the Digitalmars-d-learn mailing list