Parece-me que muitas bibliotecas C ++ maiores acabam criando seu próprio tipo de string. No código do cliente você tem que usar o que a partir da biblioteca ( QString
, CString
, fbstring
etc., tenho certeza que qualquer um pode citar alguns) ou manter a conversão entre o tipo padrão e aquela que os usos de biblioteca (que na maioria das vezes envolve pelo menos uma cópia).
Então, há uma característica específica errada ou algo errado std::string
(assim como a auto_ptr
semântica era ruim)? Isso mudou no C ++ 11?
java.lang.String
(falta de sobrecarga do operador etc.) dificultaria o uso de qualquer outra coisa.Respostas:
A maioria dessas bibliotecas C ++ maiores foi iniciada antes de
std::string
ser padronizada. Outros incluem recursos adicionais padronizados tardiamente, ou ainda não padronizados, como suporte para UTF-8 e conversão entre codificações.Se essas bibliotecas fossem implementadas hoje, provavelmente escolheriam escrever funções e iteradores que operam em
std::string
instâncias.fonte
char
é garantido que é grande o suficiente para armazenar qualquer ponto de código UTF-8. AFAIK, esse é o único "suporte" fornecido pelo C ++ 98.wchar_t
é grande o suficiente para representar todos os pontos de código Unicode. Além disso, houve toda essa discussão sobre UTF-16 considerado nocivo onde o argumento muito convincente foi feito que UTF-8 deve ser usado exclusivamente ...String é o grande embaraço de C ++.
Nos primeiros 15 anos, você não fornece uma classe de string - forçando todos os compiladores em todas as plataformas e todos os usuários a criarem seus próprios.
Então você cria algo confuso sobre se é uma API de manipulação de cadeia completa ou apenas um contêiner de char STL, com alguns algoritmos que duplicam os de um std :: Vector ou são diferentes.
Onde uma operação óbvia de strings como replace () ou mid () envolve uma confusão de iteradores, é necessário introduzir uma nova palavra-chave 'auto' para manter a declaração adequada em uma única página e levar a maioria das pessoas a desistir de todo o idioma .
E então você tem o 'suporte' unicode e o std :: wstring que é simplesmente árduo ...
<rant off> obrigado - estou me sentindo muito melhor agora.
fonte
std::string
. A falta de uma classe String em 1983 não justifica ter mais agora.Na verdade ... existem vários problemas e
std::string
, sim, fica um pouco melhor no C ++ 11, mas não vamos nos antecipar.QString
eCString
fazem parte de bibliotecas antigas ; portanto, elas existiam antes da padronização do C ++ (assim como o SGI STL). Eles tiveram que criar uma classe.fbstring
abordar preocupações de desempenho muito específicas. A Norma prescreve uma interface e a complexidade algorítmica garante mínimos, no entanto, é um detalhe de Qualidade de Implementação, se isso acaba sendo rápido ou não.fbstring
possui otimizações específicas (relacionadas ao armazenamento ou mais rápidas,find
por exemplo).Outras preocupações que não foram evocadas aqui (en vrac):
std::string
está codificando inconscientemente e não possui um código especial para UTF-8, é fácil armazenar uma string UTF-8 nela e corrompê-la inadvertidamentestd::string
Se a interface estiver inchada , muitos métodos poderiam ter sido implementados como funções livres e muitos são duplicados para se conformar tanto a uma interface baseada em índice quanto a uma interface baseada em iterador.fonte
c_str()
retorne um ponteiro para o armazenamento contíguo, o que fornece alguma interoperabilidade em C. No entanto, você não pode modificar os dados apontados. Soluções alternativas típicas incluem o uso de umvector<char>
.&s[0]
isso não importa mais tempo :)&s[0]
pode não apontar para uma string terminada em NUL (a menos quec_str()
tenha sido chamada desde a última modificação).c_str()
Returns: Um ponteirop
de tal forma quep + i == &operator[](i)
para cadai
em[0,size()]
".Além das razões postadas aqui, há também outra - a compatibilidade binária . Os escritores das bibliotecas não têm controle sobre qual
std::string
implementação você está usando e se ela possui o mesmo layout de memória que o deles.std::string
é um modelo, portanto, sua implementação é obtida nos cabeçalhos STL locais. Agora imagine que você está usando localmente alguma versão STL com desempenho otimizado, totalmente compatível com o padrão. Por exemplo, você pode optar por invadir o buffer estático em cada umstd::string
para reduzir o número de alocações dinâmicas e falhas de cache. Como resultado, o layout da memória e / ou o tamanho da sua implementação são diferentes dos da biblioteca.Se apenas o layout for diferente, algumas
std::string
funções de membro chamam instâncias transmitidas da biblioteca para o cliente ou o contrário pode falhar, dependendo de quais membros foram deslocados.Se o tamanho também for diferente, todos os tipos de bibliotecas que possuem
std::string
membros parecerão ter diferentes sizeof quando marcados na biblioteca e no código do cliente. Os membros de dados após ostd::string
membro também terão os deslocamentos deslocados, e qualquer acesso direto / acessador em linha chamado do cliente retornará lixo, apesar de "parecer bem" ao depurar a própria biblioteca.Bottomline - se a biblioteca e o código do cliente forem compilados em
std::string
versões diferentes , eles serão vinculados muito bem, mas isso pode resultar em alguns erros desagradáveis e difíceis de entender. Se você alterar suastd::string
implementação, todas as bibliotecas que expõem membros do STL deverão ser recompiladas para corresponder aostd::string
layout do cliente . E como os programadores desejam que suas bibliotecas sejam robustas, você raramente serástd::string
exposto em qualquer lugar.Para ser justo, isso se aplica a todos os tipos de STL. IIRC eles não têm layout de memória padronizado.
fonte
Existem muitas respostas para a pergunta, mas aqui estão algumas:
Legado. Muitas bibliotecas e classes de strings foram escritas ANTES da existência de std :: string.
Para compatibilidade com o código em C. A biblioteca std :: string é C ++, onde há outras bibliotecas de strings que funcionam com C e C ++.
Para evitar alocações dinâmicas. A biblioteca std :: string usa alocação dinâmica e pode não ser adequada para sistemas incorporados, interrupção ou código relacionado em tempo real ou para funcionalidade de baixo nível.
Modelos. A biblioteca std :: string é baseada em modelos. Até bem recentemente, vários compiladores C ++ tinham suporte de modelo com desempenho insuficiente ou até com erros. Infelizmente, eu trabalho em um setor que usa muitas ferramentas personalizadas e uma de nossas cadeias de ferramentas de um dos principais players do setor não "oficialmente" 100% suporta C ++ (com itens de buggy sendo modelos e outros).
Provavelmente também existem muitos outros motivos válidos.
fonte
É principalmente sobre Unicode. O suporte padrão para Unicode é péssimo, e todos têm suas próprias necessidades Unicode. Por exemplo, o ICU suporta todas as funcionalidades Unicode que você poderia desejar, por trás da interface gerada automaticamente a partir de Java mais repugnante que você possa imaginar, e se você estiver no Unix bloqueado com UTF-16, pode não ser sua ideia de um bom tempo.
Além disso, muitas pessoas precisam de níveis diferentes de suporte a Unicode - nem todo mundo precisa das APIs complexas de layout de texto e coisas assim. Portanto, é fácil ver por que existem várias classes de strings - a Standard é uma droga e todos têm necessidades diferentes das novas, sem que ninguém consiga criar uma única classe que possa executar várias plataformas cruzadas de suporte Unicode com uma interface agradável.
Na minha opinião, isso é principalmente culpa do Comitê C ++ por não fornecer corretamente suporte ao Unicode em 1998 ou 2003, talvez fosse compreensível, mas não no C ++ 11. Felizmente, em C ++ 17, eles farão melhor.
fonte
É porque todo programador tem algo a provar e sente a necessidade de criar sua própria classe de strings mais rápida e impressionante para sua única função. Geralmente é um pouco supérfluo e leva a todos os tipos de conversões extras de strings na minha experiência.
fonte