Criar o seu próprio UDLs em C ++

A biblioteca padrão, juntamente com os recursos integrados de C ++, fornecê-lo com um interessante conjunto de literais. No entanto, o verdadeiro valor de literais se torna mais evidente quando você criar o seu próprio.

Há muitas necessidades diferentes que você pode resolver usando literais (User-Defined UDLs), mas três necessidades comuns estão a apoiar as conversões de dados, tornando tipos personalizados mais fácil trabalhar com, e na obtenção de efeitos colaterais desejados sem o habitual número de problemas de codificação.

Embora built-in ou literais biblioteca padrão são fornecidos em forma prefixo e sufixo, você só pode criar o formulário sufixo ao definir seus próprios literais. Além disso, o sufixo deve começar com um sublinhado. O sublinhado serve para ajudar a evitar conflitos com sufixos existentes e assegurar outros desenvolvedores sabem que o literal é um formulário personalizado (não padrão).

Desenvolver uma conversão UDL

É possível encapsular conversões dentro de um UDL. Tudo que você precisa fazer depois de criar um tal UDL é fornecer o sufixo apropriado ao definir a constante para se obter o resultado desejado. o CustomUDL01 exemplo demonstra uma técnica para a definição de uma conversão que altera o raio de entrada para a área de um círculo na constante.

#incluir usando namespace std-constexpr longa operador double "" _circ (long double radius) {return raio * raio * 3.141592-} int main () {double x = 5.0_circ-cout lt; lt; "A área do círculo é:" lt; lt; x lt; lt; endl-retorno 0-}

A fim de criar a UDL, o exemplo baseia-se numa constexpr com um valor de retorno de um long double e um valor de entrada, raio, de um long double. A equação para calcular a área de um círculo é # 960-r2. Como você pode ver, o exemplo executa o cálculo correto como parte do constexpr.

Sempre que você criar um UDL costume, o compilador força você a usar o maior tipo para a conversão. O que isto significa é que você deve usar um long double para literais de ponto flutuante e unsigned long long representação de inteiros. Mesmo se você mais tarde optar por usar um tipo menor, como é feito neste exemplo, declarando x como um duplo, o próprio literal deve empregar o maior tipo possível.

Para declarar um UDL do novo tipo, o exemplo cria x, que utiliza o _circ sufixo. Em seguida, ele emite o ecrã resultado. Quando você executar esse exemplo, você vê que o valor correto foi colocado na x, como mostrado aqui:

A área do círculo é: 78,5398

Desenvolvendo um tipo personalizado UDL

Uma grande parte do código que você encontra depende de tipos personalizados que são difíceis de acompanhar e entender. Criando um UDL para simplificar o código torna as coisas mais claras e reduz o potencial de erro. o CustomUDL02 exemplo mostra um tipo de costume, o operador utilizado para criar a UDL, bem como a forma como a UDL é utilizado para definir um literal.

#incluir usando MyType namespace std-struct {MyType (duplo Entrada): Valor (Input) {} double Valor -} - operador MyType "" _mytype (long double Value) {return MyType (Value) -} int main () {auto UDLType = 145.6_mytype-cout lt; lt; UDLType.Value lt; lt; endl-retorno 0-}

Para que esta técnica para o trabalho, você deve criar um construtor para o seu tipo que aceita o número de entradas necessárias para configurar o tipo. No mínimo, o construtor deve aceitar um tipo ou o valor de entrada do usuário fornece está perdido.

O tipo personalizado não precisa suportar o mesmo tipo de dados de tamanho, conforme exigido pelo operador, mas eles devem ser do mesmo tipo. Por exemplo, você não poderia fazer a transição de um long double para um int.

Quando você executar este exemplo, você vê um valor de produção de 145,6, que é o valor que a entrada para o tipo personalizado. É possível lidar com configurações bastante complexas usando esta abordagem. O usuário do seu tipo personalizado obtém a capacidade de criar um código claro que é fácil de seguir e interpretar, mesmo quando os tipos subjacentes são complexos.

Usando um UDL personalizado para efeitos colaterais

Um dos usos mais interessantes para UDLs é criar efeitos colaterais (Uma operação que não seja a operação usual ou normal, quer para tornar a aplicação mais curto e mais eficiente ou para fornecer flexibilidade adicional). Você deseja definir um certo tipo de operação que ocorre como resultado da definição do literal.

O que você começa é ainda um literal, mas um literal que não necessariamente indicar um valor que você pretende usar mais tarde. o CustomUDL03 exemplo mostra um uso tão não-tradicional.

#incluir usando namespace operador std-vazio "" _countdown (long Valor longo não assinado) {for (int i = Value- i> = 0- i -) cout lt; lt; Eu lt; lt; endl-} int main () {10_countdown-retorno 0-}

Note-se que o _contagem regressiva operador não está ligado a algo que você normalmente associa com um valor. Na verdade, ele não retorna um valor. O que você recebe em vez disso é um efeito colateral. Quando você executar este exemplo, você vê esta saída.

109876543210

O que aconteceu é que o compilador tem substituído 10_countdown com indivíduo cout declarações, um para cada iteração do loop. O que você acabar com é 11 cout declarações que fornecer os valores entre 10 e 0 (em ordem inversa). O efeito colateral UDL abre todos os tipos de possibilidades interessantes para a criação de código que simplifica determinadas tarefas repetitivas de uma maneira que faz com que seu uso óbvio.

menu