1
votes

I would like to use a range as a function parameter, i.e. call something like:

foo(arr,1..23)

In the function I want to do something like

int arr[22]
arr[21] = some_other_arr[<range>]

where <range> is 1..23 from the above call.

Is that possible? How would I have to declare foo?

2
auto arr[22] = ... is not valid D code. - DejanLekic
@DejanLekic: err... I always make this mistake... - steffen
You can't do foo(arr, 1..23) but you can do foo(arr, iota(1, 23)) or similar... - DejanLekic

2 Answers

5
votes

First, 1..23 isn't a range -- it's just special syntax that works only inside foreach statements.

A range that does the same as 1..23 is iota(1, 23) from std.range; it returns a range of successive values (such as integers).

To pass a range into a function, you generally want to use templates:

void foo(Range)(Range r)
{
    foreach (e; r)
        writeln(e);
}

Which you can then call the way you want:

foo(iota(1, 23)); // print the numbers from 1 to 23 (exclusive)

Note: if arr is an array, and you want a range of the values at indices 1..23 then you can use a slice:

foo(arr[1..23]);

A slice of an array is a range.

To have a function accept this, you don't need to use templates. foo could be written:

void foo(int[] r)
{
    foreach (e; r)
        writeln(e);
}
1
votes

An array slice is the most powerful range - a random-access range. So why not simply use slice for what you need:

import std.stdio;
import std.conv;

int main() {
    int[] ina = [0, 1, 22, 11, 5, 9, 3];
    auto arr = ina[2..5];
    writeln(arr); // this is an example of a "function" with range as parameter
    return 0;
}

/*** output:
[22, 11, 5]
****/

You can toy with it here: http://dpaste.dzfl.pl/95568985 (fork and run). Frankly, I would accept Peter's answer because it shows everything you need to know. :)