to_string não é membro de std, diz g ++ (mingw)

245

Estou fazendo um pequeno programa de recordação de vocabulário, onde as palavras seriam mostradas aleatoriamente para mim em busca de significados. Eu quero usar a biblioteca C ++ padrão, como Bjarne Stroustroup nos diz, mas encontrei um problema aparentemente estranho logo de cara.

Eu quero alterar um longnúmero inteiro std::stringpara poder armazená-lo em um arquivo. Eu trabalhei to_string()para o mesmo. O problema é que, quando eu o compilo com o g ++ (versão 4.7.0, conforme mencionado no sinalizador --‍version), ele diz:

PS C:\Users\Anurag\SkyDrive\College\Programs> g++ -std=c++0x ttd.cpp
ttd.cpp: In function 'int main()':
ttd.cpp:11:2: error: 'to_string' is not a member of 'std'

Meu programa que fornece esse erro é:

#include <string>

int main()
{
    std::to_string(0);
    return 0;
}

Mas sei que não pode ser porque a biblioteca msdn diz claramente que existe e uma pergunta anterior no Stack Overflow (para g ++ versão 4.5) diz que pode ser ativada com o -std=c++0xsinalizador. O que estou fazendo de errado?

Anurag Kalia
fonte
5
Funciona com meu GCC 4.4.5 (ou seja, fornece um erro de "sobrecarga ambígua"); talvez o seu libstdc++esteja desatualizado?
21412 Fred Foo
3
Ele funciona em Ideone , que usa GCC 4.5.1.
Kerrek SB 19/10/12
5
Isso funciona para mim com o g ++ 4.6.3. Seu erro refere-se à linha 11. Você diz que seu programa "foi essencialmente reduzido a" seu código, mas o código que você postou também fornece esse erro?
Vaughn Cato
@VaughnCato - Sim, este é o programa exato. Eu devo editá-lo para torná-lo mais claro. Além disso, o que é que eu estou perdendo lá?
Anurag Kalia
2
Isso também não funciona para mim, embora eu esteja usando o GCC 5.3.1. No entanto, o que o corrige é simplesmente usar um padrão C ++ posterior - ou seja, compilando com o sinalizador -std=c++11ou superior.
Arturo don Juan

Respostas:

212

Este é um bug conhecido no MinGW. Bugzilla relevante . Na seção de comentários, você pode obter uma patch para fazê-lo funcionar com o MinGW.

Esse problema foi corrigido nas distros do MinGW-w64 superiores ao GCC 4.8.0 fornecido pelo projeto MinGW-w64 . Apesar do nome, o projeto fornece cadeias de ferramentas para 32 bits e 64 bits. A distribuição Nuwen MinGW também resolve esse problema.

Rapptz
fonte
2
Discussões adicionais aqui: stackoverflow.com/questions/8542221/…
Ben
11
Estou usando o MinGW-w64 versão 4.8.1 e não está funcionando. Copiei o programa exato da pergunta. Ainda recebo o erro 'to_string' não é membro do erro 'std'. I compilado como: g ++ -std = C ++ 0x -o tostring_test.exe tostring_test.cpp
zam664
5
@ zam664 Não sei explicar o porquê, mas comecei std::to_stringa trabalhar instalando o MinGW 4.8.1 (especificamente x32-4.8.1-posix-dwarf-rev5) por meio do MinGW-builds . Em contraste, to_stringfez não trabalho com MinGW 4.8.1 instalado, quer através do instalador "mingw-get" ou o pacote TDM-GCC.
16138 Cerran
5
O patch não foi o suficiente para mim, eu tive que #define _GLIBCXX_USE_C99 1em C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++\mingw32\bits\c++config.hcomo descrito aqui
Zook
3
@Cerran "MinGW-builds" são versões do MinGW-w64, um projeto diferente do MinGW. Uma razão pela qual o MinGW-w64 foi desativado foi para que eles pudessem, de fato, corrigir bugs como o que este tópico tratava.
27716 MM
116
#include <string>
#include <sstream>

namespace patch
{
    template < typename T > std::string to_string( const T& n )
    {
        std::ostringstream stm ;
        stm << n ;
        return stm.str() ;
    }
}

#include <iostream>

int main()
{
    std::cout << patch::to_string(1234) << '\n' << patch::to_string(1234.56) << '\n' ;
}

não esqueça de incluir #include <sstream>

edgarmtze
fonte
Existe uma maneira de incluir stod também?
Jackie
Eu chamo sua função de algum outro arquivo de origem: patch :: to_string (errorCode) (onde errorCode é int) e o compilador me dá um erro nessa linha. O erro é: referência indefinida a `std :: string patch :: to_string <int> (int &) 'Entretanto, sempre que eu incluo seu código no mesmo compilador de arquivos de origem, não reclamo. Estou tentando descobrir o que há de errado.
Nikos
1
Observe que essa não é uma solução exata em relação aos zeros à direita. O original std::to_string(0.75)geralmente retornará "0.750000"(o formato sprintf% d padrão) enquanto isso retornará "0.75". Veja aqui por motivo: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
47

Conforme sugerido, isso pode ser um problema com sua versão do compilador.

Tente usar o seguinte código para converter um longem std::string:

#include <sstream>
#include <string>
#include <iostream>

int main() {
    std::ostringstream ss;
    long num = 123456;
    ss << num;
    std::cout << ss.str() << std::endl;
}
andre
fonte
Não o executei, mas obrigado por resolver meu dilema imediato. Agora só tenho que descobrir como funciona. :)
Anurag Kalia
Apenas uma observação de que, se você deseja um std::string, deseja usá-lo .str().
Christian Mann
1
Observe que essa não é uma solução exata em relação aos zeros à direita. O original std::to_string(0.75)geralmente retornará "0.750000"(o formato sprintf% d padrão) enquanto isso retornará "0.75". Veja aqui por motivo: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
20

Use esta função ...

    #include<sstream>
    template <typename T>
    std::string to_string(T value)
    {
      //create an output string stream
      std::ostringstream os ;

      //throw the value into the string stream
      os << value ;

      //convert the string stream into a string and return
      return os.str() ;
    }

    //you can also do this
    //std::string output;
    //os >> output;  //throw whats in the string stream into the string
Nirav Patel
fonte
2
Por favor, adicione algumas explicações (pelo menos comentários) em suas respostas, não importa quão fácil o código possa ser entendido.
vefthym
4
É bom ter uma solução, mas eu acho que é geralmente melhor para descobrir por que a solução std não está compilando em vez de cortar alguma coisa juntos
Matt Coubrough
A maneira "padrão" (std :: to_string) geralmente funciona - exceto quando não funciona. sstream é a solução "padrão".
Nick Vence
Observe que essa não é uma solução exata em relação aos zeros à direita. O original std::to_string(0.75)geralmente retornará "0.750000"(o formato sprintf% d padrão) enquanto isso retornará "0.75". Veja aqui por motivo: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
12

to_string é um problema atual do Cygwin

Aqui está uma nova resposta para um tópico antigo. Um novo surgiu, mas foi rapidamente anulado, Cygwin: g ++ 5.2: 'to_string' não é membro de 'std' .

Que pena, talvez tivéssemos recebido uma resposta atualizada. Segundo o @Alex, o Cygwin g ++ 5.2 ainda não está funcionando a partir de 3 de novembro de 2015.

Em 16 de janeiro de 2015, Corinna Vinschen, mantenedora da Cygwin na Red Hat, disse que o problema era uma falha no newlib. Ele não suporta a maioria das funções duplas e, portanto, não reconhece o C99.

Red Hat é,

... ainda esperando obter a funcionalidade "long double" no newlib em um ponto.

Em 25 de outubro de 2015, Corrine também disse :

Ainda seria bom se alguém com um pouco de conhecimento matemático contribuísse com as funções duplas longas ausentes para o newlib.

Então só temos isso. Talvez um de nós que tenha conhecimento e tempo possa contribuir e ser o herói.

A Newlib está aqui .

Comunidade
fonte
Vendo como eles migraram de envio de correções via correio para git somente neste ano, parece desencorajar ...
RR
8

Alterar padrão C ++ padrão

Do erro (COMPILE FILE FAILED): 'to_string' não é membro de 'std'

-std = c ++ 98

Para (COMPILAR ARQUIVO COM SUCESSO)

-std = c ++ 11 ou -std = c ++ 14

Testado no Cygwin G ++ (GCC) 5.4.0

Joma
fonte
3

to_string () está presente apenas no c ++ 11, portanto, se a versão do c ++ for menor, use alguns métodos alternativos, como sprintf ou ostringstream

Aishwarya Mittal
fonte
2

O fato é que o libstdc ++ realmente é suportado std::to_stringnos destinos * -w64-mingw32 desde 4.8.0 . No entanto, isso não inclui suporte para MinGW.org, Cygwin e variantes (por exemplo, * -pc-msys do MSYS2). Consulte também https://cygwin.com/ml/cygwin/2015-01/msg00245.html .

Eu implementei uma solução alternativa antes que o bug fosse resolvido para o MinGW-w64. Sendo diferente do código em outras respostas, isso é uma imitação para o libstdc ++ (possível). Ele não requer construção de fluxo de sequência, mas depende das extensões libstdc ++. Mesmo agora, estou usando destinos mingw-w64 no Windows, mas ainda funciona bem para vários outros destinos (desde que as long doublefunções não sejam usadas).

FrankHB
fonte
2

Para quem se pergunta por que isso acontece no Android, provavelmente é porque você está usando uma biblioteca padrão c ++ errada. Tente alterar a biblioteca c ++ em seu build.gradle de gnustl_staticpara c++_statice o padrão c ++ em seu CMakeLists.txt de -std=gnu++11para-std=c++11

kynnysmatto
fonte
1

Se usarmos uma solução de luz de modelo (como mostrado acima) como a seguir:

namespace std {
    template<typename T>
    std::string to_string(const T &n) {
        std::ostringstream s;
        s << n;
        return s.str();
    }
}

Infelizmente, teremos problemas em alguns casos. Por exemplo, para membros const estáticos :

hpp

class A
{
public:

    static const std::size_t x = 10;

    A();
};

cpp

A::A()
{
    std::cout << std::to_string(x);
}

E ligando:

CMakeFiles/untitled2.dir/a.cpp.o:a.cpp:(.rdata$.refptr._ZN1A1xE[.refptr._ZN1A1xE]+0x0): undefined reference to `A::x'
collect2: error: ld returned 1 exit status

Aqui está uma maneira de resolver o problema (adicione ao tipo size_t ):

namespace std {
    std::string to_string(size_t n) {
        std::ostringstream s;
        s << n;
        return s.str();
    }
}

HTH.

Boris
fonte
0

nos bloqueios de código, vá para configuração -> configuração do compilador -> sinalizador do compilador -> selecione std c ++ 11 done. Eu tive o mesmo problema ... agora está funcionando!

5hifaT
fonte
-4

Isso aconteceu comigo também: acabei de escrever uma função rápida, em vez de me preocupar em atualizar meu compilador.

string to_string(int number){
    string number_string = "";
    char ones_char;
    int ones = 0;
    while(true){
        ones = number % 10;
        switch(ones){
            case 0: ones_char = '0'; break;
            case 1: ones_char = '1'; break;
            case 2: ones_char = '2'; break;
            case 3: ones_char = '3'; break;
            case 4: ones_char = '4'; break;
            case 5: ones_char = '5'; break;
            case 6: ones_char = '6'; break;
            case 7: ones_char = '7'; break;
            case 8: ones_char = '8'; break;
            case 9: ones_char = '9'; break;
            default : ErrorHandling("Trouble converting number to string.");
        }
        number -= ones;
        number_string = ones_char + number_string;
        if(number == 0){
            break;
        }
        number = number/10;
    }
    return number_string;
}
Jeff Pope
fonte
29
Este não é um substituto para std :: to_string e definitivamente não é uma resposta para a pergunta.
Verax
13
Não se esqueça de implementar o std :: cout também! É muito melhor reimplementar com muitos bugs adicionais do que descobrir o problema raiz!
jmc
você está tornando as coisas complexas demais. Apenasones_char = '0' + number % 10;
phuclv