Partilhar via


String Literal

A manipulação de seqüências literais foi alterado a partir de Managed Extensions for C++ para Visual C++ 2010.

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

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

O desempenho de sobrecarga entre as duas inicializações acontece não triviais, como a seguir CIL 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 redução notável apenas lembrando (ou aprendizagem) para uma seqüência literal de prefixo com um S. Na sintaxe de novo, a manipulação de seqüências literais se torna transparente, determinado pelo contexto de uso. O S não precisa ser especificado.

E quanto a casos em que precisamos explicitamente direcionam o compilador a interpretação de um ou outro? Nesses casos, aplicamos uma conversão explícita. For example:

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. Enquanto isso talvez não pareça muito ele altera a resolução dos conjuntos de função sobrecarregada, que incluem uma String e um const char* como parâmetros formais concorrentes. A resolução de uma vez resolvido para um const char* instância está sinalizada como ambíguo. For example:

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 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 corresponder ao nome da função que está sendo chamado. Por exemplo, desde f() é invocado por meio de uma instância de R, todas as funções nomeadas f que são não é um membro do R (ou de sua hierarquia de classe base) não são funções de candidato. Em nosso exemplo, existem duas funções do candidato. Estas são as funções de dois membros do R chamado f. Uma chamada falha durante esta fase, se o conjunto de funções do candidato está vazio.

  2. O conjunto de funções viáveis dentre 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 esta fase, se o conjunto de funções viável está vazio.

  3. Selecione a função que representa a melhor correspondência da chamada. Para fazer isso, as conversões aplicadas para transformar os argumentos para o tipo dos parâmetros da função viável de classificação. 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. Ou seja, se as conversões necessárias para transformar o tipo do argumento real para o tipo do parâmetro formal são igualmente boas. A chamada é sinalizada como ambíguo.

No Managed Extensions, a resolução dessa chamada invocado a const char* instância como melhor correspondência. Na nova sintaxe, a conversão necessária para corresponder à "abc" para const char* e String^ agora são equivalentes – ou seja, igualmente bom – e, portanto, a chamada é sinalizada como defeituosos – 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, existe 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 a colocação de conversões de tipo possíveis em uma hierarquia. Aqui está minha compreensão dessa hierarquia – essas conversões, claro, estão implícitos. Usando a notação de uma conversão explícita substitui a hierarquia semelhante à forma parênteses substitui a precedência do operador usuais de uma expressão.

  1. Recomenda-se 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 como o idioma foi alterado.

  2. Uma promoção é melhor do 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 do 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 do que uma conversão implícita de definido pelo usuário. Boxing, por exemplo, um int em um Object é melhor do que a aplicação de um operador de conversão de um SmallInt classe de valor.

  5. Uma conversão implícita de definido pelo usuário é melhor do que nenhuma conversão. Uma conversão implícita de definido pelo usuário é a última instrução de saída antes de erro (com a advertência de que a assinatura formal pode conter uma matriz de param 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 entre dois as correspondências exatas conflitantes!

Uma correspondência exata, quando isso acontece, inclui um número de conversões triviais. Existem quatro conversões triviais em ISO-c que podem ser aplicadas e ainda assim ser qualificado como uma correspondência exata. Três são chamados de lvalue transformações. Um quarto tipo é chamado de uma conversão de qualificação. Três transformações de lvalue são tratadas como uma melhor correspondência exata daquele que exigem uma conversão de qualificação.

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

Para o compilador sinalizar a chamada como ambíguo, 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 trivial. Esta é a alteração que foi introduzida na nova versão de idioma. E é por isso a chamada agora está sinalizada como ambíguo.

Consulte também

Referência

System::String Handling in Visual C++

Conceitos

Alterações de linguagem geral