Ответ 1
TL; DR. Компиляторы ведут себя так, как ожидалось.
Стандарт определяет лямбда-семантику следующим образом: [expr.prim.lambda, section 1]:
лямбда-выражение:
lambda-introducer lambda-declarator_opt compound-statement
Здесь составной оператор - это всего лишь тело лямбда между {}, потому что все остальное включено в lambda-declarator:
лямбда-описатель:
( parameter-declaration-clause ) decl-specifier-seq_opt exception-specification_opt attribute-specifier-seq_opt trailing-return-type_opt
Кроме того, в разделе 12 той же главы сказано, что
Выполнение init-capture ведет себя так, как будто оно объявляет и явно фиксирует переменную формы "auto init-capture"; чья декларативная область является составным выражением лямбда-выражений, за исключением того, что:
(12.1) - если захват копируется (см. ниже), нестатический член данных, объявленный для захвата, и переменная рассматривается как два разных способа обращения к одному и тому же объекту, который имеет время жизни нестатический элемент данных, и никакая дополнительная копия и уничтожение не выполняется, а
(12.2) - если захват по ссылке, время жизни переменных заканчивается, когда заканчивается время жизни объектов закрытия.
Итак, в вашем первом примере область переменной x
- это только тело лямбда, не включая выражение decltype
. Во втором примере, очевидно, область x
- это функция main
.