Convenientemente Declarando Strings Compile-Time em C ++

Ser capaz de criar e manipular seqüências de caracteres durante o tempo de compilação em C ++ tem vários aplicativos úteis. Embora seja possível criar strings em tempo de compilação em C ++, o processo é muito incômodo, já que a string precisa ser declarada como uma sequência variadica de caracteres, por exemplo.

using str = sequence<'H', 'e', 'l', 'l', 'o', ', ', 'w', 'o', 'r', 'l', 'd', '!'>;

Operações como concatenação de strings, extração de substrings e muitas outras, podem ser facilmente implementadas como operações em sequências de caracteres.É possível declarar cadeias de tempo de compilação mais convenientemente? Se não, existe uma proposta nos trabalhos que permita a declaração conveniente de cadeias de tempo de compilação?

Por que as abordagens existentes falham?

Idealmente, gostaríamos de poder declarar strings em tempo de compilação da seguinte maneira:

// Approach 1
using str1 = sequence<"Hello, world!">;

ou, usando literais definidos pelo usuário,

// Approach 2
constexpr auto str2 = "Hello, world!"_s;

Ondedecltype(str2) teria umconstexpr construtor. Uma versão mais confusa da abordagem 1 é possível implementar, aproveitando o fato de que você pode fazer o seguinte:

template <unsigned Size, const char Array[Size]>
struct foo;

No entanto, o array precisaria ter uma ligação externa, então, para que a abordagem 1 funcionasse, teríamos que escrever algo assim:

/* Implementation of array to sequence goes here. */

constexpr const char str[] = "Hello, world!";

int main()
{
    using s = string<13, str>;
    return 0;
}

Escusado será dizer que isto é muito inconveniente. A abordagem 2 não é realmente possível de implementar. Se tivéssemos que declarar um (constexpr) operador literal, então como podemos especificar o tipo de retorno? Como precisamos que o operador retorne uma sequência variadica de caracteres, então precisaríamos usar oconst char* parâmetro para especificar o tipo de retorno:

constexpr auto
operator"" _s(const char* s, size_t n) -> /* Some metafunction using `s` */

Isso resulta em um erro de compilação, porques não é umconstexpr. Tentando contornar isso fazendo o seguinte não ajuda muito.

template <char... Ts>
constexpr sequence<Ts...> operator"" _s() { return {}; }

O padrão determina que esse formulário de operador literal específico seja reservado para tipos de ponto flutuante e inteiro. Enquanto123_s trabalharia,abc_s não faria. E se nós abandonarmos os literais definidos pelo usuário e usarmos apenas umconstexpr função?

template <unsigned Size>
constexpr auto
string(const char (&array)[Size]) -> /* Some metafunction using `array` */

Como antes, nos deparamos com o problema que a matriz, agora um parâmetro para oconstexpr função, já não é umconstexpr tipo.

Eu acredito que deve ser possível definir uma macro de pré-processador C que leva uma string e o tamanho da string como argumentos, e retorna uma seqüência que consiste nos caracteres da string (usandoBOOST_PP_FOR, string, array subscritos e similares). No entanto, eu não tenho tempo (ou juros suficientes) para implementar essa macro =)

questionAnswers(13)

yourAnswerToTheQuestion