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.
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.