constexpr 변수가 캡처되지 않았습니다.
Dec 10 2020
다음 코드는 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'변수 는 capture-default가 지정되지 않은 람다에서 암시 적으로 캡처 할 수 없다는 것입니다 .하지만 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;
}();
}
clang이 맞습니까? 그렇다면 그 이유는 무엇입니까? -std = c ++ 17을 사용하고 있습니다.
--편집하다--
다음 질문 : 캡처하지 않고 람다에서 constexpr 값을 사용할 수 있습니까? clang11에서는 더 이상 문제가되지 않으므로이 항목과 관련이 없습니다. 실제로 위에서 언급했듯이 x가 int이면 clang11이 컴파일됩니다.
샘플 코드도 있습니다. https://godbolt.org/z/rxcYjz
답변
2 DavisHerring Dec 25 2020 at 07:09
당신이 때 return x;
첫 번째 예를 들어, 당신은 호출해야합니다 A
바인딩 포함의 복사 생성자, 참조 에 x
따라서 ODR-사용을. 상수 표현식에서 사용할 수있는 값의 사소한 복사본이 더 이상 odr-use를 구성해서는 안된다는 주장을 할 수 return x.a;
있지만 해당 규칙에는 그러한 예외가 없으므로 Clang은이 를 거부하는 것이 맞습니다 .
실제적으로, 캡처 할 필요가 없도록 모든 constexpr
변수 static
를 만들 수 있습니다 .