to_opes không phải là thành viên của std, g ++ (mingw)


245

Tôi đang thực hiện một chương trình ghi nhớ từ vựng nhỏ trong đó các từ sẽ được chiếu ngẫu nhiên vào tôi để hiểu nghĩa. Tôi muốn sử dụng thư viện C ++ tiêu chuẩn như Bjarne Stroustroup nói với chúng tôi, nhưng tôi đã gặp phải một vấn đề có vẻ kỳ lạ ngay ngoài cổng.

Tôi muốn thay đổi một longsố nguyên thành std::stringđể có thể lưu trữ nó trong một tập tin. Tôi đã làm việc to_string()cho cùng. Vấn đề là, khi tôi biên dịch nó với g ++ (phiên bản 4.7.0 như được đề cập trong cờ - đảo ngược của nó), nó nói:

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'

Chương trình của tôi đưa ra lỗi này là:

#include <string>

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

Nhưng, tôi biết điều đó không thể xảy ra bởi vì thư viện msDN nói rõ ràng nó tồn tại và một câu hỏi trước đó về Stack Overflow (đối với phiên bản g ++ 4.5) nói rằng nó có thể được bật bằng -std=c++0xcờ. Tôi đang làm gì sai?


5
Hoạt động với GCC 4.4.5 của tôi (nghĩa là có lỗi "quá tải mơ hồ"); có lẽ bạn libstdc++đã lỗi thời?
Fred Foo

3
hoạt động trên Ideone , sử dụng GCC 4.5.1.
Kerrek SB

5
Điều này làm việc cho tôi với g ++ 4.6.3. Lỗi của bạn đề cập đến dòng 11. Bạn nói rằng chương trình của bạn "về cơ bản đã được giảm xuống" mã của bạn, nhưng mã bạn đã đăng cũng có lỗi đó không?
Vaughn Cato

@VaughnCato - Đúng là chương trình chính xác. Tôi nên chỉnh sửa nó để làm cho nó rõ ràng hơn. Ngoài ra, tôi đang làm gì ở đó?
Anurag Kalia

2
Điều này cũng không hiệu quả với tôi, mặc dù tôi đang sử dụng GCC 5.3.1. Tuy nhiên, những gì khắc phục nó chỉ đơn giản là sử dụng một tiêu chuẩn C ++ sau này - tức là bằng cách biên dịch với cờ -std=c++11hoặc cao hơn.
Arturo don Juan

Câu trả lời:


212

Đây là một lỗi được biết đến theo MinGW. Bugzilla có liên quan . Trong phần bình luận, bạn có thể lấy một bản vá để làm cho nó hoạt động với MinGW.

Sự cố này đã được khắc phục trong các bản phát hành MinGW-w64 cao hơn GCC 4.8.0 do dự án MinGW-w64 cung cấp . Mặc dù tên, dự án cung cấp các bộ công cụ cho 32 bit cùng với 64 bit. Bản phân phối Nuwen MinGW cũng giải quyết vấn đề này.


2
Thảo luận thêm tại đây: stackoverflow.com/questions/8542221/ Kiếm
Ben

11
Tôi đang sử dụng MinGW-w64 phiên bản 4.8.1 và nó không hoạt động. Tôi đã sao chép chương trình chính xác từ câu hỏi. Tôi vẫn nhận được 'to_ chuỗi' không phải là thành viên của lỗi 'std'. Tôi đã biên dịch nó dưới dạng: g ++ -std = c ++ 0x -o toopes_test.exe toopes_test.cpp
zam664

5
@ zam664 Tôi không thể giải thích lý do, nhưng tôi std::to_stringphải làm việc bằng cách cài đặt MinGW 4.8.1 (cụ thể, x32-4.8.1-posix-dwarf-rev5) thông qua các bản dựng MinGW . Ngược lại, to_stringđã không làm việc với MinGW 4.8.1 cài đặt thông qua một trong hai trình cài đặt "mingw-get" hoặc gói TDM-GCC.
Cerran

5
Các miếng vá là không đủ đối với tôi, tôi đã phải #define _GLIBCXX_USE_C99 1C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++\mingw32\bits\c++config.hnhư đã mô tả ở đây
Zook

3
@Cerran "MinGW-builds" là bản dựng của MinGW-w64, một dự án khác với MinGW. Một lý do khiến MinGW-w64 bị chặn là vì thực tế họ có thể sửa các lỗi như lỗi mà chủ đề này đề cập đến.
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' ;
}

đừng quên bao gồm #include <sstream>


Có cách nào để bao gồm cả stod là tốt?
Jackie

Tôi gọi hàm của bạn từ một số tệp nguồn khác: patch :: to_opes (errorCode) (trong đó errorCode là int) và trình biên dịch cho tôi một lỗi tại dòng đó. Lỗi là: không xác định tham chiếu đến `std :: string patch :: to_opes <int> (int &) 'Tuy nhiên, bất cứ khi nào tôi đưa mã của bạn vào cùng một trình biên dịch tệp nguồn đều không phàn nàn. Tôi đang cố gắng tìm ra những gì sai.
Nikos

1
Xin lưu ý rằng đây không phải là một giải pháp chính xác liên quan đến các số 0 ở cuối. Bản gốc std::to_string(0.75)thường sẽ trả về "0.750000"(định dạng sprintf% d mặc định) trong khi điều này sẽ trả về "0.75". Xem tại đây để biết lý do: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko

47

Theo đề xuất, đây có thể là một vấn đề với phiên bản trình biên dịch của bạn.

Hãy thử sử dụng mã sau đây để chuyển đổi longthành std::string:

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

int main() {
    std::ostringstream ss;
    long num = 123456;
    ss << num;
    std::cout << ss.str() << std::endl;
}

Tôi đã không chạy nó nhưng cảm ơn bạn đã giải quyết tình trạng khó xử ngay lập tức của tôi. Bây giờ tôi chỉ phải tìm ra cách nó hoạt động. :)
Anurag Kalia

Chỉ cần một lưu ý rằng nếu bạn muốn một std::string, bạn muốn sử dụng .str()thay thế.
Christian Mann

1
Xin lưu ý rằng đây không phải là một giải pháp chính xác liên quan đến các số 0 ở cuối. Bản gốc std::to_string(0.75)thường sẽ trả về "0.750000"(định dạng sprintf% d mặc định) trong khi điều này sẽ trả về "0.75". Xem tại đây để biết lý do: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko

20

Sử dụng chức năng này ...

    #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

2
Xin vui lòng, thêm một số lời giải thích (ít nhất là nhận xét) trong câu trả lời của bạn, bất kể mã có thể dễ hiểu đến mức nào.
vefthym

4
Thật tốt khi có một cách giải quyết, nhưng tôi nghĩ rằng tốt nhất là tìm ra lý do tại sao giải pháp tiêu chuẩn không biên dịch thay vì hack một cái gì đó cùng nhau
Matt Coubrough

Cách "chuẩn" (std :: to_opes) thường hoạt động - ngoại trừ khi không. sux là cách giải quyết "chuẩn".
Nick Vence

Xin lưu ý rằng đây không phải là một giải pháp chính xác liên quan đến các số 0 ở cuối. Bản gốc std::to_string(0.75)thường sẽ trả về "0.750000"(định dạng sprintf% d mặc định) trong khi điều này sẽ trả về "0.75". Xem tại đây để biết lý do: stackoverflow.com/a/13686914/785171
Krzysztof Bociurko

12

to_opes là một vấn đề hiện tại với Cygwin

Đây là một câu trả lời mới cho một chủ đề cũ. Một cái mới đã xuất hiện nhưng nhanh chóng bị phá hủy, Cygwin: g ++ 5.2: 'to_opes' không phải là thành viên của 'std' .

Quá tệ, có lẽ chúng tôi đã nhận được một câu trả lời cập nhật. Theo @Alex, Cygwin g ++ 5.2 vẫn không hoạt động kể từ ngày 3 tháng 11 năm 2015.

Vào ngày 16 tháng 1 năm 2015, Corinna Vinschen, một người duy trì Cygwin tại Red Hat cho biết vấn đề này là một thiếu sót của newlib. Nó không hỗ trợ hầu hết các chức năng kép dài và do đó C99 không biết.

Mũ đỏ là

... vẫn hy vọng có được chức năng "nhân đôi dài" vào newlib tại một thời điểm.

Vào ngày 25 tháng 10 năm 2015 Corrine cũng cho biết ,

Sẽ vẫn tốt nếu ai đó có một chút kiến ​​thức toán học sẽ đóng góp các hàm kép dài còn thiếu cho newlib.

Vì vậy, chúng tôi đã có nó. Có lẽ một trong số chúng ta có kiến ​​thức và thời gian có thể đóng góp và trở thành người hùng.

Newlib đang ở đây .


Nhìn cách họ di chuyển từ việc gửi các bản vá qua thư đến git chỉ trong năm nay, nó cảm thấy nản lòng ...
rr-

8

Thay đổi tiêu chuẩn C ++ mặc định

Từ lỗi (TẠO FILE FILE): 'to_ chuỗi' không phải là thành viên của 'std'

-std = c ++ 98

Tới (THÀNH CÔNG FILE FILE)

-std = c ++ 11 hoặc -std = c ++ 14

Đã thử nghiệm trên Cygwin G ++ (GCC) 5.4.0


3

to_opes () chỉ có trong c ++ 11, vì vậy nếu phiên bản c ++ ít sử dụng một số phương thức thay thế như sprintf hoặc Ostringstream


2

Thực tế là libstdc ++ thực sự hỗ trợ std::to_stringtrong các mục tiêu * -w64-mingw32 kể từ 4.8.0 . Tuy nhiên, điều này không bao gồm hỗ trợ cho MinGW.org, Cygwin và các biến thể (ví dụ * -pc-msys từ MSYS2). Xem thêm https://cygwin.com/ml/cygwin/2015-01/msg00245.html .

Tôi đã triển khai một cách giải quyết trước khi lỗi được khắc phục cho MinGW-w64. Khác với mã trong các câu trả lời khác, đây là mô phỏng theo libstdc ++ (càng tốt). Nó không yêu cầu xây dựng luồng chuỗi mà phụ thuộc vào phần mở rộng libstdc ++. Ngay cả bây giờ tôi đang sử dụng các mục tiêu mingw-w64 trên Windows, nó vẫn hoạt động tốt cho nhiều mục tiêu khác (miễn là các long doublechức năng không được sử dụng).


2

Đối với bất kỳ ai thắc mắc tại sao điều này xảy ra trên Android, có lẽ là do bạn đang sử dụng một thư viện chuẩn c ++ sai. Hãy thử thay đổi thư viện c ++ trong build.gradle từ gnustl_staticsang c++_staticvà tiêu chuẩn c ++ trong CMakeLists.txt của bạn từ -std=gnu++11sang-std=c++11


1

Nếu chúng ta sử dụng một giải pháp ánh sáng mẫu (như được hiển thị ở trên) như sau:

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

Thật không may, chúng tôi sẽ có vấn đề trong một số trường hợp. Ví dụ: đối với các thành viên const tĩnh :

hpp

class A
{
public:

    static const std::size_t x = 10;

    A();
};

cpp

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

Và liên kết:

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

Đây là một cách để giải quyết vấn đề (thêm vào loại size_t ):

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

HTH.


0

trong codeblocks, hãy vào cài đặt -> cài đặt trình biên dịch -> cờ trình biên dịch -> chọn std c ++ 11 xong. Tôi đã có cùng một vấn đề ... bây giờ nó đang hoạt động!


-4

Điều này cũng xảy ra với tôi, tôi chỉ viết lên một chức năng nhanh chứ không phải lo lắng về việc cập nhật trình biên dịch của mình.

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;
}

29
Đây không phải là một thay thế cho std :: to_opes và chắc chắn không phải là một câu trả lời cho câu hỏi.
Verax

13
Đừng quên thực hiện std :: cout quá! Tốt hơn nhiều là chỉ thực hiện lại với rất nhiều lỗi bổ sung hơn là tìm ra vấn đề gốc!
jmc

bạn đang làm mọi thứ quá sức. Chỉ cầnones_char = '0' + number % 10;
phuclv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.