foreach range statement
バグにはまったら、まず @repeatedly さんに聞くのが最善。
@repeatedly foreach (i; 0..10){i-=1; writefln("%d", i); } は無限ループになるのでしょうか。もしなるならなぜですか。
2012-06-11 01:49:31@repeatedly 全く同じではないのですが、 http://t.co/MENLFEgJ が AC, http://t.co/3A3vJr5S が TLE しました。先ほどの例と何か違うのでしょうか。
2012-06-11 01:56:31@__DaLong あー,dmdがforeachをforに展開した時に同じ変数使い回してんのかなぁ.通常はrange的なアプローチだから影響しないけど,整数のforに関しては特別に高速なコードを生成している可能性が高い.iota(10)なら多分無限ループしない.
2012-06-11 02:04:16@repeatedly iota にしたら通りました。だいたいわかった気がしますが、わりと嵌まりそうです・・・。
2012-06-11 02:08:42@__DaLong まぁループのインデックスを操作する人なんて普通いないでしょ,というのが今までの言語の経験から得た結果なので,より高速なコードを生成するためにその辺のガードを緩めるのは仕方ない気もする.
2012-06-11 02:13:230..N というのは配列リテラルみたいなものだと思ってたけど、そういうわけじゃないのか。foreach とスライスにしか使えない特別な表記ってことかな。 #d_lang
2012-06-11 02:27:23とりあえず ARC 001 の C 問題を通すことができたし、D 言語に関する知見も増えたし、満足して寝ることにしよう。
2012-06-11 02:29:07たしかにループカウンタに代入を行いたいのは重複順列をコードしての全探索を簡単に書きたいときくらいだな。
2012-06-11 02:35:03翌日:
昨日わかったことを書いた。D: Foreach Range Statement http://t.co/M6zdofmA #d_lang
2012-06-11 15:09:07@mono_shoo それは具体的には何と何とが不一致であるバグという意味ですか? マニュアルと実際の挙動とが一致していることには納得しましたが、たしかに私は無限ループになっても得をすることはないと思います。
2012-06-11 21:51:57foreach (i; 0..n) が foreach (i; iota(n)) の略記なのか、for (i = 0; i < n; i += 1;) の略記なのかという問題な気がしています。どちらであるべきかは決めにくいかと。 #D @mono_shoo @repeatedly
2012-06-11 21:55:51@__DaLong @mono_shoo @repeatedly foreachの列挙変数はrefをつけない限り、列挙対象の値のコピーのように動作すべきです。従ってこの場合、変数iの変更がループ回数に影響を与えるのはバグだと思います。
2012-06-11 22:06:39個人的にはforeach (i; 0..n) {…}でiが書き換えられるのはD言語らしくないけど,Rangeじゃなくて整数範囲ステートメントを使った場合は高速に動作します!も悪くはないかな,と思わなくもない.というかコンパイラが最適化してくれればそれで良い.
2012-06-11 22:10:07