GCC constexpr lambdas dans les fonctions constexpr et évaluation au moment de la compilation

constexpr std::array code, nous avons le code suivant utilisé pour accumuler un constexpr std::array au moment de la compilation:

 template  constexpr T comstack_time_accumulator(const std::array const &A, const std::size_t i, const O& op, const T initialValue) { return (i < N) ? op(A[i], compile_time_accumulator(A, i + 1, op, initialValue)) : initialValue; } 

et l’exemple de code suivant pour tester / varify (c’est-à-dire qu’il évalue au moment de la compilation):

 constexpr std::array v {{4, 5, 6, 7}}; std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, std::plus())>::value << std::endl; 

DEMO LIVE

Maintenant, si changez l’opérateur std::plus avec un constexpr lambda:

 constexpr auto lambda_plus = [] (int x, int y) { return x + y; }; 

et appelez-le comme ci-dessous:

 constexpr std::array v {{4, 5, 6, 7}}; std::cout << std::integral_constant::value << std::endl; ^^^^^^^^^^^ 

Je reçois une erreur, que lambda n’est pas constexpr :

appel à la fonction non-constexpr ”

Maintenant, faisant une petite recherche, j’ai découvert que les constexpr ne sont pas encore supportés.

Q:

Pourquoi, si les constexpr lambdas ne sont pas pris en charge, nous sums autorisés à définir un constexpr lambda en premier lieu?

Modifier:

Il semble que Clang n’accepte pas le code . Alors quel compilateur a raison?

Le code est en effet mal formé selon [expr.const] / (2.6); Les lambdas ne sont pas encore autorisés dans les expressions constantes, bien qu’une proposition correspondante soit en circulation. GCC n’accepte pas lambda_plus la déclaration de lambda_plus .

C ++ 11 permettait une définition très limitée d’un constexpr alors que C ++ 14 avait une longue liste de n’est pas un constexpr

À partir de n4296 (version candidate pour C ++ 14) 5.20.2.6

5.20 Expressions constantes [expr.const]

2 Une expression conditionnelle e est une expression constante de base, à moins que l’évaluation de e, conformément aux règles de la machine abstraite (1.9), n’évalue l’une des expressions suivantes:

2.6) – une expression lambda (5.1.2);

Donc la réponse est que les lambda ne sont pas correctes, le compilateur doit donc se tromper.