747 votes

Différence entre « __classid » et « const »

Quelle est la différence entre et ?

  • Quand est-ce que je peux utiliser une seule d'entre elles ?
  • Quand puis-je utiliser tous les deux et Comment devrais-je choisir un ?

719voto

jogojapan Points 26661

Signification de base de la syntaxe et de

Les deux mots clés peuvent être utilisés dans la déclaration des objets ainsi que des fonctions. La différence fondamentale lorsqu'il est appliqué à des objets est ceci:

  • const déclare un objet en tant que constante. Cela implique une garantie que, une fois initialisé, la valeur de l'objet ne change pas, et le compilateur peut utiliser ce fait pour faire des optimisations. Il permet également d'éviter au programmeur d'écrire le code qui modifie les objets qui n'étaient pas destinés à être modifiés après l'initialisation.

  • constexpr déclare un objet comme à une utilisation à ce que la Norme appelle des expressions constantes. Mais notez que l' constexpr n'est pas la seule façon de le faire.

Lorsqu'il est appliqué à des fonctions de la différence de base est ceci:

  • const ne peuvent être utilisés que pour des fonctions membres statiques, pas de fonctions en général. Il donne une garantie que la fonction de membre de ne pas modifier les non-membres de données statiques.

  • constexpr peut être utilisée à la fois membre et non-membre de fonctions, que bien des constructeurs. Il déclare la fonction d'ajustement pour les utiliser dans des expressions constantes. Le compilateur ne l'accepter que si la fonction répond à certains critères (7.1.5/3,4), le plus important (†):

    • Le corps de la fonction doit être non-virtuel et extrêmement simple: en dehors de typedefs et statique affirme, un seul return déclaration est autorisé. Dans le cas d'un constructeur, seulement une liste d'initialisation, typedefs et statique affirmer sont autorisés. (= default et = delete sont permis, aussi, si.)
    • Les arguments et le type de retour doit être littérale types (c'est à dire, de façon générale, les types de données simples, généralement des scalaires ou des agrégats)

Des expressions constantes

Comme dit ci-dessus, constexpr déclare à la fois des objets ainsi que des fonctions aptes à être utilisés dans des expressions constantes. Une expression constante est plus que simplement de la constante:

  • Il peut être utilisé dans des endroits qui nécessitent de la compilation d'évaluation, par exemple, des paramètres de modèle et la matrice de taille prescripteurs:

    template <int N>
    class fixed_size_list
    { /*...*/ };
    
    fixed_size_list<X> mylist;     // <-- X must be an integer constant expression
    
    int numbers[X];   // <-- X must be an integer constant expression
    
  • Mais attention:

    • Déclarer que quelque chose comme constexpr ne garantit pas nécessairement qu'il sera évalué au moment de la compilation. Il peut être utilisé pour un tel, mais il peut être utilisé dans d'autres endroits qui sont évalués au moment de l'exécution, ainsi.

    • Un objet peut être adapté pour une utilisation dans des expressions constantes , sans être déclaré constexpr. Exemple:

      int main() {
        const int N = 3;
      
        int numbers[N] = { 1 , 2, 3 };   // <-- N is constant expression
        /*...*/
      }
      

    Cela est possible parce qu' N, être constant et initialisé au moment de la déclaration avec un littéral, satisfait aux critères d'une expression constante, même si elle n'est pas déclarée constexpr.

Quand donc en fait, j'ai utiliser constexpr?

  • Un objet comme N ci-dessus peut être utilisé comme expression constante sans être déclaré constexpr. Cela est vrai pour tous les objets qui sont:

    • const
    • d'intégrales ou de type énumération et
    • initialisé au moment de la déclaration avec une expression qui est elle-même une expression constante

    [Ceci est dû au §5.19/2: Une constante de l'expression ne doit pas inclure les sous-expressions qui implique "une lvalue-à-rvalue modification, sauf si [...] un glvalue de l'intégrale ou type d'énumération [...]". Merci à Richard Smith pour la correction de mes revendication précédente que c'était vrai pour tous littérale types]

  • Pour une fonction à être utilisé dans des expressions constantes, il doit être explicitement déclarée constexpr; il n'est pas suffisant pour simplement satisfaire aux critères d'constante de l'expression des fonctions. Exemple:

    template <int N>
    class list
    { };
    
    constexpr int sqr1(int arg)
    { return arg*arg; }
    
    int sqr2(int arg)
    { return arg*arg; }
    
    int main()
    {
      const int X = 2;
    
      list<sqr1(X)> mylist1; // OK; sqr1 is constexpr
      list<sqr2(X)> mylist2; // Wrong; sqr2 is not constexpr
    
      return 0;
    }
    

Quand puis-je / dois-je utiliser les deux, const et constexpr ensemble?

a) Dans l'objet de déclarations , Ce n'est jamais nécessaire lorsque les deux mots-clés renvoient à l'objet même d'être déclarée. constexpr implique const.

constexpr const int N = 5;

est le même que

constexpr int N = 5;

Toutefois, notez qu'il peut y avoir des situations où les mots clés de chaque désigner les différentes parties de la déclaration:

static constexpr int N = 3;
int main()
{
  constexpr const int *NP = &N;
  return 0;
}

Ici, NP est déclarée comme une adresse constante de l'expression, c'est à dire un pointeur qui est elle-même une expression constante. (Ce qui est possible lorsque l'adresse est généré par l'application de l'adresse de l'opérateur statique/global d'expression constante.) Ici, les deux constexpr et const sont requis: constexpr toujours se réfère à l'expression d'être déclaré (ici NP), tandis que l' const désigne int (il déclare un pointeur-à-const). Retrait de l' const rendrait l'expression illégales (parce que (a) un pointeur vers un non-const objet ne peut pas être une expression constante et (b) &N est en fait un pointeur vers une constante).

b) En fonction de membre de déclarations En C++11, constexpr implique const également pour les fonctions de membres. Cependant, il est susceptible de changer en C++14. Selon les projets actuels, constexpr implique const seulement pour les objets, pas pour les fonctions de membre, en raison d'un changement proposé au §7.1.5/8. Par conséquent, un membre de la fonction déclarée en vertu de C++11

constexpr void f();

devront être déclarées comme

constexpr void f() const;

en vertu de C++14, de manière à toujours être utilisable en tant que const fonction. Meilleur marque de votre constexpr fonctions de membre en tant que const , même maintenant, de manière à éviter d'avoir à changer beaucoup de code plus tard.


(†) Les conditions d'acceptabilité de la constexpr fonctions seront probablement détendu pour le C++14. Une proposition de Richard Smith a récemment été adoptée dans le C++14 projet.

146voto

Karthik T Points 19418

const s'applique pour les variables, et les empêche d'être modifié dans votre code.

constexpr indique au compilateur que cette expression des résultats dans un moment de la compilation, la valeur de la constante, de sorte qu'il peut être utilisé dans des endroits comme la matrice des longueurs, l'attribution d' const variables, etc. Le lien donné par Oli a un grand nombre d'excellents exemples.

Essentiellement, ils sont 2 concepts différents en tout, et peuvent (et doivent) être utilisés ensemble.

43voto

Mustafa Ekici Points 2879

Selon le livre "Le Langage de Programmation C++ 4ème Édition" par Bjarne Stroustrup
const: ce qui signifie à peu près ‘je promets de ne pas modifier cette valeur" (§7.5). Ceci est utilisé principalement pour spécifier des interfaces, de sorte que les données peuvent être transmises à des fonctions sans crainte d'être modifiée.
Le compilateur applique à la promesse faite par const.
constexpr: ce qui signifie à peu près ‘pour être évaluée au moment de la compilation" (§10.4). C'est principalement utilisé pour spécifier des constantes, afin de permettre
Par exemple:

const int dmv = 17; // dmv is a named constant
int var = 17; // var is not a constant
constexpr double max1 = 1.4*square(dmv); // OK if square(17) is a constant expression
constexpr double max2 = 1.4∗square(var); // error : var is not a constant expression
const double max3 = 1.4∗square(var); //OK, may be evaluated at run time
double sum(const vector<double>&); // sum will not modify its argument (§2.2.5)
vector<double> v {1.2, 3.4, 4.5}; // v is not a constant
const double s1 = sum(v); // OK: evaluated at run time
constexpr double s2 = sum(v); // error : sum(v) not constant expression

Pour une fonction soit utilisable dans une expression constante, qui est, dans une expression qui sera évaluée par le compilateur, il doit être défini constexpr.
Par exemple:

constexpr double square(double x) { return x∗x; }


Pour être constexpr, une fonction doit être plutôt simple: juste un retour-déclaration de calcul d'une valeur. Un constexpr fonction peut être utilisée pour les non-constante des arguments, mais quand c'est fait, le résultat n'est pas un expression constante. Nous permettons à un constexpr fonction qui doit être appelée avec des non-constante-l'expression des arguments dans des contextes qui ne nécessitent pas des expressions constantes, de sorte que nous n'avons pas le vha e pour définir essentiellement la même fonction deux fois: une fois pour les expressions constantes et une fois pour les variables.
Dans quelques endroits, des expressions constantes sont requis par les règles de la langue (p. ex., les limites du tableau (§2.2.5, §7.3), les étiquettes de caisse (§2.2.4, §9.4.2), certains arguments de modèle (§25.2), et les constantes déclarées à l'aide de constexpr). Dans d'autres cas, au moment de la compilation d'évaluation est important pour la performance. Indépendamment de les problèmes de performance, la notion de l'immuabilité (d'un objet avec une immuable de l'état) est un de conception important sujet de préoccupation (§10.4).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X