2017-06-28 5 views
0

J'apprenais constexpr et, pour ma compréhension, constexpr dit au compilateur de calculer les fonctions au cours de la compilation au lieu de temps d'exécution. J'ai utilisé le code suivant pour tester mais j'ai rencontré une erreur que je ne comprends vraiment pas. Pouvez-vous s'il vous plaît expliquer pourquoi?Erreur de compilation: Utilisez constexpr pour déclarer std :: array taille

#include <iostream> 
#include <array> 
using namespace std; 

constexpr int foo(int i) 
{ 
    return i + 5; 
} 

int main() 
{ 
    int i = 10; 
    std::array<int, foo(5)> arr; // OK 
    // But... 
    std::array<int, foo(i)> arr1; // Error 
} 

L'erreur est: la valeur de « i » ne sont pas utilisables dans une expression constante. Pourquoi? i est déclaré à l'avance pourquoi doit-il être un const?

Répondre

5

for my understanding constexpr tells the compiler to calculate functions during compile time instead of running time.

Pas exactement: avec constexpr le compilateur peut (ne doit pas) la fonction de calcul le temps de compilation. Et le compilateur le fait quand c'est nécessaire et possible.

En cas de

std::array<int, foo(5)> arr; // OK 

il est nécessaire (parce que le deuxième argument de modèle de std::array doit être connu au moment de la compilation) et possible (parce que 5 est connu au moment de la compilation).

Mais avec

int i = 10; 
std::array<int, foo(i)> arr1; // Error 

il est nécessaire (std::array), mais pas possible (parce i est une variable et le compilateur ne peut pas utiliser la valeur i pas constante compilation, mais seulement le temps d'exécution).

C'est nécessaire mais pas possible, donc l'erreur.

Mais vous pouvez écrire

int i { 10 }; 
int j { foo(i) }; 

car il est impossible appel foo(i) temps de compilation, mais il ne faut pas (parce que j peuvent être initialisés temps d'exécution). Donc foo(i) est appelé (soi-disant) temps d'exécution.

Pour compilez le std::array en utilisant foo(i), vous devez définir i comme constexpr (ou const)

constexpr int i { 10 }; 

de sorte que le compilateur peut utiliser la valeur de i temps de compilation.

Why? i is declared beforehand why does it have to be a const?

Réponse courte: parce que le standard C++ 11 le dit. Réponse longue: parce que, de cette façon, il est plus simple de construire un compilateur. Si vous voulez utiliser un temps de compilation, vous pouvez le déclarer comme constexpr et le compilateur vérifier qu'il n'est jamais modifié. C'est (relativement) simple à faire.

Sinon, si vous pouviez utiliser la valeur d'une variable non constante lors de la compilation, le compilateur devrait suivre l'histoire d'une variable pour déterminer sa valeur lorsqu'elle est utilisée dans une fonction constexpr. Dans votre exemple de jouet est simple, dans la vraie vie serait un cauchemar.