Si consideri il seguente codice (available on gcc.godbolt.org):Utilizzando un lambda in un `funzione di constexpr` in un contesto non-`constexpr`: clang vs gcc
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();
}
Compila sotto g ++ 5.3.x e più recente (incluso g ++ 6.xx).
non si compila sotto clang ++ 3.7.x e più nuovo con il seguente errore:
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; });
Una soluzione possibile per rendere il codice compilare sia con gcc e clang utilizza un "livello di riferimento indiretto" con decltype
, anche eliminare lo constexpr
nella funzione in cui è definito il lambda: gcc.godbolt.org link.
Quale compilatore è corretto in base allo standard?
In ogni caso, forse più pertinente alla tua domanda: fai uno qualsiasi dei compilatori che collaudi affermando che 'get_x()' può essere usato in un'espressione costante? In caso contrario, è la tua domanda "sono autorizzato ad aggiungere' constexpr' a funzioni che non possono mai essere utilizzate in espressioni costanti? " – hvd
@hvd: Riguardo al punto e virgola, compilo sempre codice reale con '-Wpedantic', che mi informa dell'errore. Sono abituato a scrivere codice lambda-pesante ('auto l = [] {...};') così a volte il mio cervello aggiunge automaticamente un punto e virgola alla fine di una funzione. –
@hvd È valido C++ 11 - il ';' è una * dichiarazione vuota *. Vedi [CWG 569] (http://wg21.link/cwg569). –