D言語にはstd.conv.to
という便利な関数がある。
これは配列の型も変換できるのだが、いままでうまく使えなくて毎回.map!(to!long)
とかしてた。
この記事は自分みたいなエラーメッセージを読まない悲しい人間をこれ以上産まないためにある。
うまくいかないパターン
import std.conv : to;
string[] a = ["1", "2", "3", "4", "5"];
long[] b = a.to!long[];
assert(b == [1, 2, 3, 4, 5]);
string
の配列をlong
の配列に変換したいのだが、これではコンパイルできない。
手元の DMD (v2.081.1) では以下のようなエラーが出る。
/usr/include/dlang/dmd/std/conv.d(222): Error: template std.conv.toImpl cannot deduce function from argument types !(long)(string[]), candidates are:
(中略)
app.d(5): Error: template instance `std.conv.to!long.to!(string[])` error instantiating
app.d(5): Error: only one index allowed to index long
エラーメッセージを読め
つまりこういうことだ。 エラーが出ているのはこのコードである。
long[] b = a.to!long[];
上のコードはこんな感じに解釈されている。
long[] b = a.to!(long)()[];
こうして見ると何が問題かすぐにわかる (眠くて語彙が消失している)。
解決
テンプレート引数をカッコで囲んでやればいい。
long[] b = a.to!(long[]);
こうしてやると正常に動くようになる。 1年くらい気づかずにいた気がする。 ひどい。