読者です 読者をやめる 読者になる 読者になる

【D言語】forwardについて【std.algorithm】

今回は、std.algorithmに最近追加された、forwardテンプレートについて見ていきます。

auto refな引数


D言語を使っていると、引数をauto refにすることがよくあると思います。 引数がauto refだと、右辺値を渡されたときは非ref、左辺値を渡されたときはrefになります。


void hoge()(auto ref int i){
    i = 5;
}

void main(){
    int i = 0;
    assert(i == 0);
    hoge(0);
    assert(i == 0);
    hoge(i);
    assert(i == 5);
}

auto refな引数を関数に渡す


auto refな引数を、refと非refでオーバーロードしている関数に渡すと、どうなるでしょうか?


import std.stdio;
int hoge()(auto ref int i){
    return piyo(i);
}

int piyo(int i){
    return 1;
}

int piyo(ref int i){
    return 2;
}

void main(){
    int i;
    hoge(1).writeln();
    hoge(i).writeln();
}

結果は、以下のようになります。


2
2

refなpiyoしか呼ばれていませんね。 これは、関数の引数は左辺値であるためです。 constでも無い限り、関数の引数にも代入は行えますよね。 しかし、hogeに右辺値を渡した時、非refなpiyoが呼ばれて欲しい場合もあります。

そこでforwardですよ


std.algorithm.forwardを使うと、引数の非ref性を保って関数に渡すことができます。


import std.stdio, std.algorithm;
int hoge()(auto ref int i){
    return piyo(forward!i);
}

int piyo(int i){
    return 1;
}

int piyo(ref int i){
    return 2;
}

void main(){
    int i;
    hoge(1).writeln();
    hoge(i).writeln();
}

結果は、以下のようになります。


1
2

ちゃんと、hogeに右辺値を渡した時に、非refなpiyoが呼ばれていますね!!

まとめ


std.algorithm.forwardを見てきました。 最近は、Phobosに大きな動き(破壊的変更)はありませんが、 PhobosGithubを見る限り、日々少しづつ変わっていっています。 ワクワクしますね。

担当:美馬(staticなforeachと普通のforeach、二つとも同じ構文だから紛らわしい気がする)