переменная constexpr не захвачена
Следующий код не компилируется в clang (это происходит в GCC):
struct A{
int a;
};
auto test(){
constexpr A x{10};
return []{
return x; // <-- here x is A: clang doesn't compile
}();
}
Ошибка Clang заключается в том, что переменная 'x' не может быть неявно захвачена в лямбда- выражении без указания значения захвата по умолчанию , но я думал, что переменные constexpr захватываются всегда.
Если x - int, код компилируется:
auto test(){
constexpr int x{10};
return []{
return x; // <-- here x is int: clang is ok
}();
}
Интересно, что следующий код также компилируется:
auto test(){
constexpr A x{10};
return []{
return x.a;
}();
}
Правильно ли лязг? Если да, то в чем причина? Я использую -std = c ++ 17
--РЕДАКТИРОВАТЬ--
Следующий вопрос: могу ли я использовать значение constexpr в лямбде без его захвата? не имеет отношения к этому, так как с clang11 это больше не проблема: на самом деле, как указано выше, если x является int, clang11 компилируется.
Пример кода также присутствует в https://godbolt.org/z/rxcYjz
Ответы
Когда вы return x;
в первом примере, вы должны вызвать A
«s конструктор копирования, который включает в себя обязывающее ссылку на x
и , таким образом , УСО-использует. Можно привести аргумент, что тривиальная копия значения, используемого в константных выражениях, не должна представлять собой odr-use более чем return x.a;
, но в этом правиле нет такого исключения, поэтому Clang прав, чтобы отклонить его.
На практике вы, конечно, можете создать любую constexpr
переменную, static
чтобы избежать ее захвата.