【D言語】なぜInputRangeをin引数で受け取れないのか

const教信者の方などは、すべての引数にinを付けたくなるかと思います。 が、引数にInputRangeを取る場合、それができません。 正確に言うと、出来ますが、InputRangeのはずなのに、InputRangeのように使えません。

なぜか


基本的に、InputRangeを引数に取る場合、テンプレート関数にします。


import std.array;

auto add(Range)(Range range)
{
    auto a = range.front;
    range.popFront();
    return a + range.front;
}

void main()
{
    [1, 2].add().writeln();
}

上のコードで、rangeにinをつけるとどうでしょう?


auto add(Range)(in Range range)
{
    auto a = range.front;
    range.popFront(); // !!
    return a + range.front;
}

そうです、popFrontが使えません!! popFrontは、意味的にrange内部の状態を変える関数のはずなので、そのrangeがconstであれば、当然使えません。 それどころか、frontがconstな関数である保証もどこにもありません。 frontすら、使えるかどうかが怪しいのです。

まとめ


InputRangeを引数に取るときは、inをつけることを諦めましょう。 そもそも、InputRangeは走査子なので、inをつけること自体が的を射てないのかも知れません。

担当:美馬(けど、やっぱり悲しい)