to_string nie jest członkiem standardu, mówi g ++ (mingw)

245

Tworzę mały program do zapamiętywania słownictwa, w którym słowa byłyby dla mnie przypadkowo błyskane dla znaczeń. Chcę używać standardowej biblioteki C ++, jak mówi nam Bjarne Stroustroup, ale natknąłem się na pozornie dziwny problem od samego początku.

Chcę zmienić longliczbę całkowitą na std::string, aby móc zapisać ją w pliku. Pracowałem to_string()dla tego samego. Problem polega na tym, że kiedy kompiluję go za pomocą g ++ (wersja 4.7.0, jak wspomniano w jego flagi --‍version), mówi:

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'

Mój program, który powoduje ten błąd, to:

#include <string>

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

Ale wiem, że tak nie może być, ponieważ biblioteka msdn wyraźnie mówi, że istnieje, a wcześniejsze pytanie dotyczące przepełnienia stosu (dla g ++ w wersji 4.5) mówi, że można ją włączyć za pomocą -std=c++0xflagi. Co ja robię źle?

Anurag Kalia
źródło
5
Działa z moim GCC 4.4.5 (tzn. Daje błąd „niejednoznacznego przeciążenia”); może twój libstdc++jest przestarzały?
Fred Foo,
3
To działa na Ideone , który wykorzystuje GCC 4.5.1.
Kerrek SB,
5
Działa to dla mnie z g ++ 4.6.3. Twój błąd odnosi się do wiersza 11. Mówisz, że twój program „został zasadniczo zredukowany do” twojego kodu, ale czy kod, który opublikowałeś, również zawiera ten błąd?
Vaughn Cato,
@VaughnCato - Tak, to jest dokładnie ten program. Powinienem go edytować, aby był bardziej przejrzysty. Co więcej, co tam robię?
Anurag Kalia,
2
To również nie działa dla mnie, mimo że korzystam z GCC 5.3.1. Jednak to, co naprawia, to po prostu użycie późniejszego standardu C ++ - tj. Kompilacja z flagą -std=c++11lub wyższą.
Arturo don Juan

Odpowiedzi:

212

Jest to znany błąd w MinGW. Odpowiednia Bugzilla . W sekcji komentarzy możesz uzyskać łatkę, która będzie działać z MinGW.

Ten problem został rozwiązany w dystrybucjach MinGW-w64 wyższych niż GCC 4.8.0 dostarczonych przez projekt MinGW-w64 . Pomimo nazwy, projekt zapewnia łańcuchy narzędzi dla wersji 32-bitowej wraz z wersją 64-bitową. Nuwen MinGW distro rozwiązuje również ten problem.

Rapptz
źródło
2
Dalsza dyskusja tutaj: stackoverflow.com/questions/8542221/...
Ben
11
Używam MinGW-w64 w wersji 4.8.1 i nie działa. Dokładnie skopiowałem program z pytania. Nadal dostaję, że „to_string” nie jest członkiem błędu „std”. Skompilowałem go jako: g ++ -std = c ++ 0x -o tostring_test.exe tostring_test.cpp
zam664
5
@ zam664 Nie mogę wyjaśnić, dlaczego, ale zacząłem std::to_stringpracować, instalując MinGW 4.8.1 (konkretnie x32-4.8.1-posix-dwarf-rev5) za pomocą kompilacji MinGW . W przeciwieństwie do tego, to_stringzrobił nie praca z MinGW 4.8.1 zainstalowany albo za pośrednictwem „MinGW-get” instalatora lub pakietu TDM-GCC.
Cerran
5
Łatka nie było dla mnie za mało, musiałem #define _GLIBCXX_USE_C99 1w C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++\mingw32\bits\c++config.hsposób opisany tutaj
Zook
3
@Cerran „Kompilacje MinGW” to kompilacje MinGW-w64, projektu innego niż MinGW. Jednym z powodów, dla których MinGW-w64 został rozwidlony, było to, że mogli oni naprawiać błędy, takie jak ten, o którym był ten wątek.
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' ;
}

nie zapomnij dołączyć #include <sstream>

edgarmtze
źródło
Czy istnieje sposób na włączenie również stod?
Jackie
Wywołuję twoją funkcję z innego pliku źródłowego: patch :: to_string (errorCode) (gdzie errorCode to int), a kompilator podaje mi błąd w tym wierszu. Błąd jest następujący: niezdefiniowane odniesienie do `std :: string patch :: to_string <int> (int &) 'Jednak gdy dołączę kod do tego samego kompilatora plików źródłowych, nie narzeka. Próbuję dowiedzieć się, co jest nie tak.
Nikos,
1
Należy pamiętać, że nie jest to dokładne rozwiązanie w odniesieniu do zer końcowych. Oryginał std::to_string(0.75)zwykle zwróci "0.750000"(domyślny format sprintf% d), a ten zwróci "0.75". Zobacz przyczynę: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
47

Zgodnie z sugestią może to być problem z wersją kompilatora.

Spróbuj użyć następującego kodu, aby przekonwertować plik longna 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
źródło
Nie uruchomiłem go, ale dziękuję za rozwiązanie mojego bezpośredniego dylematu. Teraz muszę tylko dowiedzieć się, jak to działa. :)
Anurag Kalia,
Tylko uwaga, że ​​jeśli chcesz std::string, chcesz użyć .str()zamiast tego.
Christian Mann
1
Należy pamiętać, że nie jest to dokładne rozwiązanie w odniesieniu do zer końcowych. Oryginał std::to_string(0.75)zwykle zwróci "0.750000"(domyślny format sprintf% d), a ten zwróci "0.75". Zobacz przyczynę: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
20

Użyj tej funkcji ...

    #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
źródło
2
Dodaj do swoich wyjaśnień (przynajmniej komentarze), bez względu na to, jak łatwy może być kod.
vefthym
4
Dobrze jest mieć obejście, ale myślę, że zwykle najlepiej jest dowiedzieć się, dlaczego standardowe rozwiązanie nie kompiluje się, a nie zhakuje coś razem
Matt Coubrough
Sposób „standardowy” (std :: to_string) często działa - z wyjątkiem sytuacji, gdy nie działa. sstream to „standardowe” obejście.
Nick Vence
Należy pamiętać, że nie jest to dokładne rozwiązanie w odniesieniu do zer końcowych. Oryginał std::to_string(0.75)zwykle zwróci "0.750000"(domyślny format sprintf% d), a ten zwróci "0.75". Zobacz przyczynę: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko
12

to_string to aktualny problem z Cygwin

Oto nowa odpowiedź na stary wątek. Pojawiło się nowe, ale zostało szybko unieważnione, Cygwin: g ++ 5.2: „to_string” nie jest członkiem „std” .

Szkoda, może otrzymalibyśmy zaktualizowaną odpowiedź. Według @Alex, Cygwin g ++ 5.2 nadal nie działa od 3 listopada 2015.

16 stycznia 2015 r. Corinna Vinschen, opiekunka Cygwin w Red Hat, powiedziała, że ​​problemem jest wada newlib. Nie obsługuje większości długich podwójnych funkcji i dlatego nie obsługuje C99.

Red Hat jest,

... wciąż mam nadzieję, że funkcja „long double” zostanie w pewnym momencie dodana do newlib.

W dniu 25 października 2015 Corrine powiedział również ,

Byłoby miło, gdyby ktoś z odrobiną wiedzy matematycznej przyczyniłby się do braku długich podwójnych funkcji w newlib.

Więc mamy to. Być może jeden z nas, który ma wiedzę i czas, może przyczynić się i zostać bohaterem.

Newlib jest tutaj .

Społeczność
źródło
Widząc, jak migrowali z wysyłania łatek pocztą do git dopiero w tym roku, to zniechęca ...
rr-
8

Zmień domyślny standard C ++

Błąd From (COMPILE FILE FAILED): „to_string” nie jest członkiem „std”

-std = c ++ 98

Do (SKŁADANIE PLIKU POMYŚLNIE)

-std = c ++ 11 lub -std = c ++ 14

Testowane na Cygwin G ++ (GCC) 5.4.0

Joma
źródło
3

to_string () jest obecny tylko w c ++ 11, więc jeśli wersja c ++ jest mniejsza, użyj alternatywnych metod, takich jak sprintf lub ostringstream

Aishwarya Mittal
źródło
2

Faktem jest, że libstdc ++ faktycznie jest obsługiwany std::to_stringw celach * -w64-mingw32 od wersji 4.8.0 . Nie obejmuje to jednak obsługi MinGW.org, Cygwin i wariantów (np. * -Pc-msys z MSYS2). Zobacz także https://cygwin.com/ml/cygwin/2015-01/msg00245.html .

Zaimplementowałem obejście, zanim błąd został rozwiązany dla MinGW-w64. W odróżnieniu od kodu w innych odpowiedziach, jest to naśladowanie libstdc ++ (jak to możliwe). Nie wymaga budowy strumienia łańcuchów, ale zależy od rozszerzeń libstdc ++. Nawet teraz używam mingw-w64 w systemie Windows, nadal działa dobrze dla wielu innych celów (o ile long doublefunkcje nie są używane).

FrankHB
źródło
2

Dla każdego, kto zastanawia się, dlaczego tak się dzieje na Androidzie, to prawdopodobnie dlatego, że używasz niewłaściwej standardowej biblioteki c ++. Spróbuj zmienić bibliotekę c ++ w build.gradle z gnustl_staticna c++_statici standard c ++ w pliku CMakeLists.txt z -std=gnu++11na-std=c++11

kynnysmatto
źródło
1

Jeśli użyjemy rozwiązania szablon-światło (jak pokazano powyżej), takie jak:

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

Niestety w niektórych przypadkach będziemy mieć problemy. Na przykład dla stałych stałych statycznych :

hpp

class A
{
public:

    static const std::size_t x = 10;

    A();
};

cpp

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

I łączenie:

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

Oto jeden ze sposobów rozwiązania problemu (dodaj do typu size_t ):

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

HTH.

Boris
źródło
0

w blokach kodu przejdź do ustawienia -> ustawienie kompilatora -> flaga kompilatora -> wybierz gotowe st c c ++ 11 gotowe. Miałem ten sam problem ... teraz działa!

5hifaT
źródło
-4

To samo mi się przydarzyło, właśnie napisałem szybką funkcję zamiast martwić się o aktualizację mojego kompilatora.

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
źródło
29
To nie jest substytutem dla std :: to_string i zdecydowanie nie jest odpowiedzią na pytanie.
Verax,
13
Nie zapomnij też wdrożyć std :: cout! O wiele lepiej jest po prostu ponownie wdrożyć z wieloma dodatkowymi błędami, niż rozwikłać problem root!
jmc
robisz rzeczy nadmiernie skomplikowane. Po prostuones_char = '0' + number % 10;
phuclv