Être capable de créer et de manipuler des chaînes de caractères lors de la compilation en C++ dispose de plusieurs applications utiles. Bien qu'il est possible de créer au moment de la compilation des chaînes en C++, le processus est très lourd, que la chaîne de caractères doit être déclaré comme un variadic séquence de caractères, par exemple:
using str = sequence<'H', 'e', 'l', 'l', 'o', ', ', 'w', 'o', 'r', 'l', 'd', '!'>;
Des opérations telles que la concaténation de chaîne, sous-chaîne d'extraction, et beaucoup d'autres, peuvent être facilement mises en œuvre que les opérations sur les séquences de caractères. Est-il possible de déclarer au moment de la compilation des chaînes plus facilement? Si non, est-il une proposition dans les œuvres qui permettrait à la pratique de la déclaration de la compilation des chaînes?
Pourquoi Les Approches Existantes De L'Échec
Idéalement, nous aimerions être en mesure de déclarer au moment de la compilation des chaînes comme suit:
// Approach 1
using str1 = sequence<"Hello, world!">;
ou, à l'aide définis par l'utilisateur littéraux,
// Approach 2
constexpr auto str2 = "Hello, world!"_s;
où decltype(str2)
aurait un constexpr
constructeur. Une messier version de la méthode 1 est possible de mettre en œuvre, en tirant parti du fait que vous pouvez effectuer les opérations suivantes:
template <unsigned Size, const char Array[Size]>
struct foo;
Toutefois, le tableau aurait besoin d'avoir une liaison externe, afin d'obtenir de 1 à travailler, vous devez écrire quelque chose comme ceci:
/* Implementation of array to sequence goes here. */
constexpr const char str[] = "Hello, world!";
int main()
{
using s = string<13, str>;
return 0;
}
Inutile de dire que cela est très gênant. Approche 2 est en fait pas possible de mettre en œuvre. Si nous étions à déclarer (constexpr
) littérale de l'opérateur, alors comment pourrions-nous préciser le type de retour? Depuis que nous avons besoin l'opérateur pour retourner un variadic séquence de caractères, de sorte que nous aurions besoin d'utiliser l' const char*
paramètre pour spécifier le type de retour:
constexpr auto
operator"" _s(const char* s, size_t n) -> /* Some metafunction using `s` */
Il en résulte une erreur de compilation, car s
n'est pas un constexpr
. En essayant de contourner ce problème en procédant de la manière suivante n'aide pas beaucoup.
template <char... Ts>
constexpr sequence<Ts...> operator"" _s() { return {}; }
La norme veut que ce spécifique littérale de l'opérateur formulaire est réservé pour l'entier et les types à virgule flottante. Alors qu' 123_s
, abc_s
ne le serait pas. Si nous fossé définis par l'utilisateur littéraux tout à fait, et juste utiliser un constexpr
fonction?
template <unsigned Size>
constexpr auto
string(const char (&array)[Size]) -> /* Some metafunction using `array` */
Comme avant, nous rencontrons le problème est que le tableau, maintenant un paramètre à l' constexpr
fonction, est en lui-même n'est plus un constexpr
type.
Je crois qu'il devrait être possible de définir un préprocesseur C macro qui prend une chaîne de caractères et la taille de la chaîne en argument, et renvoie une séquence comprenant les caractères dans la chaîne (à l'aide d' BOOST_PP_FOR
, stringification, tableau des indices, etc). Cependant, je n'ai pas le temps (ou suffisamment d'intérêt) pour mettre en œuvre une telle macro =)