Quand un constexpr fonction évaluée au moment de la compilation?
Car il est possible qu'une fonction déclarée comme constexpr peut être appelé au cours de l'exécution, en vertu de laquelle les critères retenus par le compilateur décider de le calculer au moment de la compilation ou au cours de l'exécution?
template<typename base_t, typename expo_t>
constexpr base_t POW(base_t base, expo_t expo)
{
return (expo != 0 )? base * POW(base, expo -1) : 1;
}
int main(int argc, char** argv)
{
int i = 0;
std::cin >> i;
std::cout << POW(i, 2) << std::endl;
return 0;
}
Dans ce cas, je n'est pas connu au moment de la compilation, ce qui est probablement la raison pour laquelle le compilateur traite POW() comme une fonction qui est appelée lors de l'exécution. Cette dynamique cependant, comme pratique, comme cela peut apparaître à, a quelques pas pratique implications. Par exemple, pourrait-il y avoir un cas où je voudrais le compilateur pour calculer une constexpr fonction lors de la compilation, le compilateur décide de la traiter comme une fonction normale au lieu de cela, quand il aurait travaillé au cours de la compilation-temps ainsi? Sont-ils connus et les pièges les plus courants?
- Autant que je sache, lorsque tous les arguments sont des expressions constantes.
- Et si j'écris
POW((unsigned __int64)2, 63)
. Serait-ce encore le comte comme une expression constante? - En fait, c'est plus complexe que ça je pense. Je pense que
constexpr
ne doit être évaluée lorsque son résultat est utilisé comme un paramètre du modèle, tableau lié, ou d'autres partie intégrante de la constante. Tout autre temps est une optimisation. En fait, même quand l'expression constante arguments, il peut être nécessaire d'exécuter au moment de l'exécution.constexpr int func(int p) { return !p ? 1 : throw std::exception("HI");}
doit être évalué au moment de l'exécution lorsque la non-zéro. - Les initialiseurs qui sont des expressions constantes font partie de la statique de la phase d'initialisation, par exemple
constexpr int a = POW(5, 4);
. C'est essentiellement calculée au moment de la compilation. Mais bien sûr, vous pouvez toujours utiliserPOW
dans d'autres endroits. - À moins que le résultat de la fonction est utilisée dans votre susmentionnés constante de l'expression "requirerers", alors il va donner une erreur de compilation à cause de l'exception.
- J'ai couru hors de l'espace de commentaire, mais oui 😀
- connexes: stackoverflow.com/questions/14294271/...
Vous devez vous connecter pour publier un commentaire.
constexpr
fonctions sera être évaluée au moment de la compilation lorsque tous ses arguments sont des expressions constantes et le résultat est utilisé dans une expression constante ainsi. Une expression constante peut être un littéral (comme42
), un non-type de modèle argument (commeN
danstemplate<class T, size_t N> class array;
), unenum
la déclaration de l'élément (commeBlue
dansenum Color { Red, Blue, Green };
, une autre variable déclarée constexpr, et ainsi de suite.Ils pourrait être évaluées lors de tous ses arguments sont des expressions constantes et le résultat est pas utilisé dans une expression constante, mais c'est jusqu'à la mise en œuvre.
STATIC_ASSERT_CONSTEXPR( pow(2,3) )
, mais je ne suis pas avoir beaucoup de chance...constexpr
fonctions sont évaluées au moment de la compilation si tous les arguments sont des expressions constantes? Je crois que la seule chose que dit la Norme, c'est queconstexpr
fonctions peuvent être utilisées dans des contextes qui doivent être évalués au moment de la compilation, par exemple arguments de modèle. Autre chose est le compilateur de décider. C'est du moins ce que j'ai cru jusqu'à présent.constexpr int f();
et de déclarer ensuite une expression constanteconstexpr int a = f();
. Votre réponse suggère quea
sera évaluée au moment de la compilation, carf
estconstexpr
, tous ses arguments sont aussi, et le résultat est utilisé dans unconstexpr
. Mais je crois que c'est forcément true uniquement sia
est utilisé dans un contexte qui exige au moment de la compilation d'évaluation, par exemple, un argument de modèle. Aussi, j'ai vu le lien, mais puisque c'est une SORTE de réponse, les faits pertinents, esp. Standard citations, faut le mettre ici.constexpr
variable est un expression constante, qui exige au moment de la compilation de l'évaluation. La norme citations sont non-normatif des notes; les exigences pourconstexpr
fonctions pour être évaluée au moment de la compilation sont implicitement tout au long de la norme à chaque fois que ça parle d'un expression constante.a
pourrait alors être utilisé comme un modèle d'argument ou d'un autre contexte qui exige au moment de la compilation de l'évaluation, qui je pense est implicite dans son évaluation afin d'être toujours effectué au moment de la compilation. Mais je comprends votre point, vous devriez demander à la ISO C++ post pour attirer l'attention de ceux qui sont impliqués dans la prise de cette fonctionnalité...a
dans votre exemple, doit être évaluée au moment de la compilation, et de ne pas faire la remarque carrément mal. Je ne suis pas sûr que c'est effectivement garantie par la norme à ce point...constexpr
est une expression constante, mais c'est seulement garanti pour être évaluée au moment de la compilation si c'est utilisé en tant que une expression constante (par exemple, utilisé comme argument de modèle). Mais qu'est-ce que cela veut dire?constexpr
fonction qui accepte une valeur à virgule flottante (ou en fait n'importe quel type que vous voulez) et qui renvoie un entier, puis l'utiliser à l'intérieur d'un modèle non-type de paramètre.constexpr size_t check_nonintegral_constexpr(float v) { return sizeof v; } std::array<check_nonintegral_constexpr(pow(2.0, 4))> assertion;
La fonction doit être évaluée au moment de la compilation quand une expression constante est nécessaire.
La méthode la plus simple pour garantir cela est d'utiliser un
constexpr
valeur, oustd::integral_constant
:ou:
ou
ou
std::cout << POW(2, 63) << std::endl
pourrait ne pas être évaluées lors de la compilation, depuis le cout ne nécessite pas une expression constante de la valeur?constexpr auto
méthode.std::cout << *[](){static constexpr auto expr = POW(1.113, 11); return &expr;}() << std::endl;
static
fondamentalement signifie "l'endroit sur le segment de données"? Quel est le problème avec un pointeur car il ne peut pas disparaître? @GManNickG Mais la fonction sera évaluée au moment de la compilation dans tous les cas, correct?*[]
. J'ai fait cela pour s'assurer que l'instruction return n'est pas la copie de l'objet.#define FORCE_CT_EVAL(func) [](){constexpr auto ___expr = func; return std::move(___expr);}()
operator()
de la lambda objet? C'est exactement ce que je vois avecgdb
. Non seulement cela,operator()
pourrait ne pas être constexpr lui-même et vous pourriez être en forçant au moment de l'exécution de l'évaluation.