配列リテラルと静的配列の初期化
配列リテラル追加されたけど全然使って無かったよなあ、とふと思ったので使ってみたんですが…
まずこれが通らなくてがっかり。
auto ary = [[1, 2, 3], [4, 5, 6]]; // Error: cannot implicitly convert expression ([[1,2,3],[4,5,6]]) of type int[3][2] to int
そして更に、これが通らないのは正直どうなんだろう…
int[3][2] ary = [[1, 2, 3], [4, 5, 6]]; // Error: cannot implicitly convert expression ([[1,2,3],[4,5,6]]) of type int[3][2] to int
ちなみにこれは通る。
int[3][] ary = [[1, 2, 3], [4, 5, 6]]; int[][] ary_ = [[1, 2, 3], [4, 5, 6]];
二次元以上の静的配列の初期化が腐っているんでしょうか…ガッカリです。
というか「cannot implicitly convert int[3][2] to int」って何事…それ暗黙の変換じゃなくてもできないよ!
そういえば http://d.hatena.ne.jp/kurimura/20061003 の auto + 配列リテラルですが、一次元配列ならうまく動くようになっていました。
auto ary = [1.0, 2.0]; writefln(typeid(typeof(ary))); // double[2]
ここで auto 偉いねー、で終われると嬉しいんですが、問題は更にあります。
二次元以上の動的配列を、二次元以上の配列リテラルでない静的配列で初期化しようとするときにもエラーが発生します。
toDynamic!(T) test(T)(T t){ toDynamic!(T) ret = t; return ret; } void main(){ int[] one = test([1, 2, 3]); // ok int[][] two = test([[1, 2, 3], [4, 5, 6]]); // Error: cannot implicitly convert expression (t) of type int[3][2] to int[][] }
ガッカリ祭です。
追記:二次元以上の静的配列を引数に受け取り、動的配列を返す関数テンプレートをとりあえず載せておきます。
toDynamic!(T)[] tt(T)(T[] ary){ static if (isStaticArray!(T)){ toDynamic!(T)[] ret; foreach (t;ary){ ret ~= test(t); } return ret; } else { return ary; } }
頭使ってないので色々効率悪かったり動かなかったりするかもしれません…
メモ:toDynamicテンプレートが静的配列を持つ動的配列に使えない気がする