Compartilhar via


Seqüência Literal

A manipulação de literais de cadeia de caracteres foi alterado de Managed Extensions for C++ para Visual C++.

No design de linguagem Managed Extensions for C++, uma string gerenciada literal foi indicada, antecedendo a seqüência de caracteres literal com um S.Por exemplo:

String *ps1 = "hello";
String *ps2 = S"goodbye";

O desempenho sobrecarga entre duas inicializações acontece ser não triviais, como CIL seguinte representação demonstra como visto pelo ildasm:

// String *ps1 = "hello";
ldsflda    valuetype $ArrayType$0xd61117dd
     modopt([Microsoft.VisualC]Microsoft.VisualC.IsConstModifier) 
     '?A0xbdde7aca.unnamed-global-0'

newobj instance void [mscorlib]System.String::.ctor(int8*)
stloc.0

// String *ps2 = S"goodbye";
ldstr      "goodbye"
stloc.0

Que é uma economia notável apenas lembrando (ou aprendizagem) para uma seqüência literal de prefixo com um S.Na nova sintaxe, a manipulação de literais de cadeia de caracteres é feita transparente, determinado pelo contexto de uso.O S não precisa ser especificado.

Como casos em que precisamos explicitamente direcionam o compilador a interpretação de um ou outro?Nesses casos, podemos aplicar uma conversão explícita.Por exemplo:

f( safe_cast<String^>("ABC") );

Além disso, a seqüência de caracteres literal agora coincide com um String com uma conversão simple, em vez de uma conversão padrão.Embora isso talvez não pareça muito altera a resolução de conjuntos de função sobrecarregada que incluem um String e um const char* como concorrentes parâmetros formais.A resolução de uma vez resolvido para um const char* instância agora é sinalizada como ambíguo.Por exemplo:

ref struct R {
   void f(const char*);
   void f(String^);
};

int main () {
   R r;
   // old syntax: f( const char* );
   // new syntax: error: ambiguous
   r.f("ABC"); 
}

Por que há uma diferença?Desde a mais de uma instância nomeada f existe dentro do programa, isso requer que o algoritmo de resolução de sobrecarga de função a ser aplicado para a chamada.A resolução formal de uma função de sobrecarga envolve três etapas.

  1. A coleção das funções do candidato.As funções de candidatos são esses métodos dentro do escopo lexicalmente corresponde ao nome da função que está sendo chamado.Por exemplo, desde f() é invocado por uma instância de R, todos os denominado funções f que não são membros do R (ou de sua hierarquia de classe base) não são funções do candidato.Em nosso exemplo, há duas funções do candidato.Essas são as funções de dois membros do R chamado f.Uma chamada falha durante essa fase se o conjunto de função candidato está vazio.

  2. O conjunto de funções viáveis entre as funções do candidato.Uma função viável é aquele que pode ser chamado com os argumentos especificados na chamada, dado o número de argumentos e seus tipos.Em nosso exemplo, ambos os candidatos são também viáveis funções.Uma chamada falha durante essa fase se o conjunto de função viável está vazio.

  3. Selecione a função que representa a melhor correspondência da chamada.Isso é feito por classificação as conversões aplicadas para transformar os argumentos para o tipo dos parâmetros de função viável.Isso é relativamente direta com a função de uma único parâmetro; ele se torna um pouco mais complexo quando há vários parâmetros.Uma chamada falha durante essa fase se não houver nenhuma correspondência melhor.Isto é, se as conversões necessárias para transformar o tipo do argumento real para o tipo de parâmetro formal forem igualmente boas.A chamada é sinalizada como ambíguo.

Em extensões gerenciadas, a resolução desta chamada chamado a const char* instância como a melhor correspondência.Na sintaxe de novo, a conversão necessária para coincidir com "abc" para const char* e String^ agora são equivalentes – ou seja, igualmente BOM – e, portanto, a chamada é sinalizada como incorreta – ou seja, como ambíguo.

Isso nos leva a duas perguntas:

  • Qual é o tipo do argumento real, "abc"?

  • O que é o algoritmo para determinar quando uma conversão de tipo é melhor que outro?

O tipo de seqüência de caracteres literal "abc" é const char[4] – Lembre-se de um caractere de terminação nulo implícito no final de cada seqüência de caracteres é literal.

O algoritmo para determinar quando uma conversão de tipo é melhor que outro envolve colocar as conversões de tipo possíveis em uma hierarquia.Aqui está minha compreensão de hierarquia – essas conversões, obviamente, serão implícitos.Usando uma notação de conversão explícita substitui a hierarquia semelhante à maneira como parênteses substitui a precedência de operador normal de uma expressão.

  1. Melhor é uma correspondência exata.Surpreendentemente, um argumento ser uma correspondência exata, ele não precisa coincidir exatamente com o tipo de parâmetro; Ele só precisa ser o suficiente.Esta é a chave para compreender o que está acontecendo neste exemplo e mudou o idioma.

  2. Uma promoção é melhor que uma conversão padrão.Por exemplo, promovendo um short int para um int é melhor do que a conversão de um int em um double.

  3. Uma conversão padrão é melhor que uma conversão boxing.Por exemplo, convertendo um int em um double é melhor que boxing um int em um Object.

  4. Uma conversão boxing é melhor que uma conversão implícita definida pelo usuário.Boxing, por exemplo, um int em um Object é melhor do que aplicar um operador de conversão de um SmallInt valor de classe.

  5. Uma conversão implícita definida pelo usuário é melhor que nenhuma conversão.Uma conversão implícita definida pelo usuário é a última saída antes de erro (com a limitação que a assinatura formal pode conter uma matriz de parâmetro ou reticências nessa posição).

Portanto, o que significa dizer que uma correspondência exata não é necessariamente exatamente uma correspondência?Por exemplo, const char[4] não coincidir exatamente com o const char* ou String^, e ainda a ambigüidade do nosso exemplo está entre dois correspondências exatas conflitantes!

Uma correspondência exata, como acontece, inclui um número de conversões simples.Há quatro conversões simples em C++ ISO que podem ser aplicadas e qualificar ainda como uma correspondência exata.Três são chamados como lvalue transformações.Um quarto tipo é chamado uma conversão de qualificação.Três transformações lvalue são tratadas como uma melhor correspondência exata daquele que requer uma conversão de qualificação.

Um formulário da transformação lvalue é a conversão nativo matriz ao ponteiro.Este é o que está envolvido na correspondência de um const char[4] para const char*.Portanto, a correspondência de f("abc") para f(const char*) é uma correspondência exata.Em manifestações anteriores do nosso idioma, isso era na verdade a melhor correspondência.

O compilador sinalizar a chamada como ambígua, portanto, requer que a conversão de um const char[4] para um String^ também ser uma correspondência exata através de uma conversão simples.Esta é a alteração foi introduzida na nova versão de idioma.E é por isso a chamada agora é sinalizada como ambíguo.

Consulte também

Referência

Cadeia de caracteres (Extensões de Componentes C++)

Conceitos

Alterações gerais em linguagens (C++/CLI)