>>780
for(auto e: vec){ statement }
はこんな感じで展開される
{
 auto && __range = vec;

 for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) {
  auto e = *__begin;
  statement
 }
}
ポイントとしては内部でイテレータを使ってるからイテレータ無効化ルールに抵触したらおかしな動きになる
(ループの中でvec.push_back()をするとか)。

二つ目の質問については、上の例の
 auto && __range = vec;
のように最初に定義域を右辺値参照で取ってるからsetの定義を外に出す必要はない