Рассмотрим этот пример, который объявляет переменную как constexpr, захватывает ее копией в лямбда и объявляет другую переменную constexpr, которая является результатом функции constexpr, которая разворачивает нестандартный шаблонный параметр из исходной переменной.
#include <utility>
template<int I>
constexpr auto unwrap(std::integral_constant<int, I>) {
return I;
}
int main() {
constexpr auto i = std::integral_constant<int, 42>{};
constexpr auto l = [i]() {
constexpr int x = unwrap(i);
};
}
Clang (trunk) принимает этот код. (wandbox)
Ошибка GCC (trunk) со следующим сообщением об ошибке (wandbox):
lambda_capture.cpp:11:31: error: the value of ‘i’ is not usable in a constant expression
constexpr int x = unwrap(i);
^
lambda_capture.cpp:10:28: note: ‘i’ was not declared ‘constexpr’
constexpr auto l = [i]() {
Какой компилятор прав? Мне кажется, что это ошибка GCC, где constessprness lambda capture не правильно распространяется на лямбда-контекст.