Il semble évident que constexpr implique const et donc il est courant de voir:
constexpr int foo = 42; // no const here
Cependant si vous écrivez:
constexpr char *const str = "foo";
Ensuite, GCC générera "avertissement: conversion obsolète de la constante de chaîne en" char * "" si l'indicateur -Wwrite-string est passé.
L'écriture:
constexpr const char *const str = "foo";
résout le problème.
Donc constexpr const et constexpr sont-ils vraiment les mêmes?
Le problème est que dans une déclaration de variable, constexpr
applique toujours le const
- ness à l'objet déclaré; const
d'autre part peut s'appliquer à un type différent, selon l'emplacement.
Donc
constexpr const int i = 3;
constexpr int i = 3;
sont équivalents;
constexpr char* p = nullptr;
constexpr char* const p = nullptr;
sont équivalents; les deux font p
un pointeur const
vers char
.
constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;
sont équivalents. constexpr
crée p
un const
pointeur. Le const
dans const char *
fait p
pointer vers const char
.
Le message d'erreur que vous voyez n'a rien à voir avec le mot clé constexpr
en soi.
Une chaîne littérale comme "foo", comme dans:
somefunction("foo");
Le type de ce littéral de chaîne est const char *
. La déclaration suivante:
char *const str = "foo";
Cela tente d'attribuer un const char *
valeur à char *
valeur. La résultante char *
la valeur n'est pas modifiable, constante, mais à ce moment-là, l'erreur s'est déjà produite: une tentative de conversion d'un const char *
à un char *
.
Le mot clé constexpr
dans votre exemple n'est qu'une distraction et n'a aucune incidence sur l'erreur.