tilisation de C++ 11, Ubuntu 14.04, chaîne d'outils par défaut de GCC.
Ce code échoue:
constexpr std::string constString = "constString";
error: le type 'const string {aka const std :: basic_string}' de la variable constexpr 'constString' n'est pas littéral ... car ... 'std :: basic_string' a un destructeur non trivial
Est-il possible d'utiliser std::string
dans aconstexpr
? (apparemment pas ...) Si oui, comment? Existe-t-il un autre moyen d'utiliser une chaîne de caractères dans un constexpr
?
Non, et votre compilateur vous a déjà fourni une explication complète.
Mais vous pouvez faire ceci:
constexpr char constString[] = "constString";
Au moment de l'exécution, cela peut être utilisé pour construire un std::string
lorsque cela est nécessaire.
En C++ 17, vous pouvez utiliser string_view
:
_constexpr std::string_view sv = "hello, world";
_
Un _string_view
_ est un objet de type string
qui agit comme une référence immuable et non propriétaire de toute séquence d'objets char
.
Comme le problème est lié au destructeur non trivial, il est donc possible de définir une instance constexpr
de ce type si le destructeur est supprimé du std::string
. Comme ça
struct constexpr_str {
char const* str;
std::size_t size;
// can only construct from a char[] literal
template <std::size_t N>
constexpr constexpr_str(char const (&s)[N])
: str(s)
, size(N - 1) // not count the trailing nul
{}
};
int main()
{
constexpr constexpr_str s("constString");
// its .size is a constexpr
std::array<int, s.size> a;
return 0;
}
C++ 20 ajoutera constexpr
chaînes et vecteurs
La proposition suivante a été acceptée apparemment: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0980r0.pdf et il ajoute des constructeurs tels que:
// 20.3.2.2, construct/copy/destroy
constexpr
basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
constexpr
explicit basic_string(const Allocator& a) noexcept;
constexpr
basic_string(const basic_string& str);
constexpr
basic_string(basic_string&& str) noexcept;
en plus des versions constexpr de toutes/la plupart des méthodes.
Il n'y a pas de support à partir de GCC 9.1.0, la compilation suivante échoue:
#include <string>
int main() {
constexpr std::string s("abc");
}
avec:
g++-9 -std=c++2a main.cpp
avec erreur:
error: the type ‘const string’ {aka ‘const std::__cxx11::basic_string<char>’} of ‘constexpr’ variable ‘s’ is not literal
std::vector
discuté à: Impossible de créer constexpr std :: vector
Testé dans Ubuntu 19.04.