Pergunta

Na verdade, esta não é uma questão de design, embora possa parecer.(Bem, ok, é uma questão de design).O que estou me perguntando é por que o C++ std::fstream as aulas não demoram std::string em seu construtor ou métodos abertos.Todo mundo adora exemplos de código, então:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::string filename = "testfile";      
    std::ifstream fin;

    fin.open(filename.c_str()); // Works just fine.
    fin.close();

    //fin.open(filename); // Error: no such method.
    //fin.close();
}

Isso me incomoda o tempo todo quando trabalho com arquivos.Certamente a biblioteca C++ usaria std::string qualquer lugar possível?

Foi útil?

Solução

Pegando uma string C, o C++03 std::fstream classe reduziu a dependência do std::string aula.No C++ 11, no entanto, o std::fstream classe permite passar um std::string para seu parâmetro construtor.

Agora, você pode se perguntar por que não existe uma conversão transparente de um std:string para uma string C, então uma classe que espera uma string C ainda pode levar um std::string assim como uma classe que espera um std::string pode pegar uma string C.

A razão é que isso causaria um ciclo de conversão, que por sua vez poderia levar a problemas.Por exemplo, suponha std::string seria conversível em uma string C para que você pudesse usar std::stringestá com fstreamS.Suponha também que a string C seja conversível em std::strings como é o estado no padrão atual.Agora, considere o seguinte:

void f(std::string str1, std::string str2);
void f(char* cstr1, char* cstr2);

void g()
{
    char* cstr = "abc";
    std::string str = "def";
    f(cstr, str);  // ERROR:  ambiguous
}

Porque você pode converter de qualquer maneira entre um std::string e uma string C a chamada para f() poderia resolver qualquer um dos dois f() alternativas e, portanto, é ambígua.A solução é quebrar o ciclo de conversão tornando explícita uma direção de conversão, que é o que o STL escolheu fazer com c_str().

Outras dicas

Existem vários locais onde o comitê do padrão C++ não otimizou realmente a interação entre recursos na biblioteca padrão.

std::string e seu uso na biblioteca é um deles.

Um outro exemplo é std::swap.Muitos contêineres têm uma função de membro swap, mas nenhuma sobrecarga de std::swap é fornecida.O mesmo vale para std::sort.

Espero que todas essas pequenas coisas sejam corrigidas no próximo padrão.

Talvez seja um consolo:todos os fstream obtiveram um open(string const &, ...) próximo ao open(char const *, ...) no rascunho de trabalho do padrão C++0x.(ver, por exemplo27.8.1.6 para a declaração basic_ifstream)

Então, quando for finalizado e implementado, você não vai mais pegar :)

A biblioteca stream IO foi adicionada à biblioteca C++ padrão antes do STL.Para não quebrar a compatibilidade com versões anteriores, foi decidido evitar a modificação da biblioteca IO quando o STL foi adicionado, mesmo que isso significasse alguns problemas como o que você levantou.

@ Bernardo:
Monólitos "não formaram". "Tudo para um e um para todos" pode funcionar para os mosqueteiros, mas não funciona tão bem para os designers de classe.Aqui está um exemplo que não é totalmente exemplar e ilustra o quanto você pode errar quando o design se transforma em overdesign.O exemplo, infelizmente, foi retirado de uma biblioteca padrão perto de você...~ http://www.gotw.ca/gotw/084.htm

É inconsequente, isso é verdade.O que você quer dizer com a interface do std::string sendo grande?O que significa grande, neste contexto - muitas chamadas de método?Não estou sendo jocoso, estou realmente interessado.

Ela tem mais métodos do que realmente precisa, e seu comportamento de usar deslocamentos integrais em vez de iteradores é um pouco duvidoso (pois é contrário ao modo como o resto da biblioteca funciona).

O verdadeiro problema, creio, é que a biblioteca C++ tem três partes;possui a antiga biblioteca C, possui o STL e possui strings e iostreams.Embora alguns esforços tenham sido feitos para unir as diferentes partes (por ex.a adição de sobrecargas à biblioteca C, porque C++ suporta sobrecarga;a adição de iteradores a basic_string;a adição dos adaptadores do iterador iostream), há muitas inconsistências quando você olha os detalhes.

Por exemplo, basic_string inclui métodos que são duplicatas desnecessárias de algoritmos padrão;os vários métodos find, provavelmente poderiam ser removidos com segurança.Outro exemplo:localidades usam ponteiros brutos em vez de iteradores.

C++ cresceu em máquinas menores do que os monstros para os quais escrevemos código hoje.Na época em que o iostream era novo, muitos desenvolvedores realmente se importavam com o tamanho do código (eles tinham que ajustar todo o programa e dados em várias centenas de KB).Portanto, muitos não queriam usar a "grande" biblioteca de strings C++.Muitos nem usaram a biblioteca iostream pelos mesmos motivos, tamanho do código.

Não tínhamos milhares de megabytes de RAM para distribuir como temos hoje.Normalmente não tínhamos vinculação em nível de função, então estávamos à mercê do desenvolvedor da biblioteca para usar muitos arquivos de objetos separados ou então extrair toneladas de código desnecessário.Todo esse FUD fez com que os desenvolvedores se afastassem do std::string.

Naquela época eu evitava std::string também."Muito inchado", "chamado de malloc com muita frequência", etc.Tolamente usando buffers baseados em pilha para strings e depois adicionando todos os tipos de código tedioso para garantir que ele não seja excedido.

Existe alguma classe em STL que receba uma string ...Acho que não (não consegui encontrar nenhum na minha pesquisa rápida).Portanto, provavelmente é uma decisão de design que nenhuma classe em STL deva depender de qualquer outra classe STL (que não seja diretamente necessária para funcionalidade).

Acredito que isso foi pensado e feito para evitar a dependência;ou seja#include <fstream> não deve forçar #include <string>.

Para ser honesto, esta parece ser uma questão bastante inconsequente.Uma pergunta melhor seria: por que a interface do std::string é tão grande?

Hoje em dia você pode resolver esse problema com muita facilidade:adicionar -std=c++11 para o seu CFLAGS.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top