Рассмотрим следующий код (available on gcc.godbolt.org):Использование лямбда в `constexpr` функции в не `constexpr` контексте: лязг против НКУ
template <typename TF>
constexpr auto fn_x(TF f)
{
return f();
}
constexpr auto get_x()
{
return fn_x([]{ return 0; });
}
int main()
{
auto res = get_x();
}
Он компилирует под 5.3.x г ++ и новее (включая g ++ 6.xx).
Это не компилируется под лязгом ++ 3.7.x и новее со следующей ошибкой:
error: constexpr function never produces a constant expression [-Winvalid-constexpr]
constexpr auto get_x()
^
note: subexpression not valid in a constant expression
return fn_x([]{ return 0; });
Возможное решение сделать код компилировать как с НКУ и лязгом использует «слой косвенности» с decltype
, также избавляясь от constexpr
в функции, где определена лямбда: gcc.godbolt.org link.
Какой компилятор здесь указан в соответствии со стандартом?
В любом случае, возможно, более релевантный вашему вопросу: какой-либо из компиляторов, с которыми вы тестируете, утверждает, что 'get_x()' может использоваться в постоянном выражении? Если нет, возникает вопрос: «Я могу добавить' constexpr' к функциям, которые никогда не могут использоваться в постоянных выражениях? » – hvd
@hvd: Что касается точек с запятой, я всегда компилирую настоящий код с помощью '-Wpedantic', который информирует меня об ошибке. Я привык писать лямбда-тяжелый код ('auto l = [] {...};'), поэтому иногда мой мозг автоматически добавляет точку с запятой в конце функции. –
@hvd Это действительно C++ 11 - ';' является * пустой декларацией *. См. [CWG 569] (http://wg21.link/cwg569). –