2017-04-13 14 views
5

Tôi chỉ biết rằng C++ có một số std::to_string() được xác định trong <string>. Bây giờ tôi tự hỏi tại sao to_string() chỉ hoạt động với các loại số. Có lý do cụ thể nào không, tại sao không có một tổng quát hơnTại sao chỉ có `to_string()` cho các loại số?

template <typename T> 
std::string to_string(const T& t); 

?

thể được thực hiện như thế này:

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

tôi nghi ngờ rằng đó là chung to_string không tồn tại, bởi vì nó rất dễ dàng để viết riêng của bạn, nhưng lập luận tương tự sẽ áp dụng đối với các to_string() tham int, double, v.v.

+0

Chỉ cần hai xu của tôi ... Nhưng những chức năng này là cách quá giới hạn để được xứng đáng được trong std ... Một cái gì đó như Boost.Format hoặc lexical_cast sẽ có được rất nhiều, và tôi có nghĩa là hữu ích hơn rất nhiều. Các hàm to_string này rất cơ bản và chỉ hữu dụng trong các kịch bản cơ bản nhất, có nghĩa là chúng vô dụng trong cuộc sống thực. – rubenvb

+7

Đừng bỏ qua một phiếu bầu. Có thể chỉ là một người có một ngày tồi tệ. –

+3

Thực tế, có một đề xuất về vấn đề này http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0117r0.html, nhưng đừng nghĩ rằng nó sẽ được chấp nhận đôi khi – DAle

Trả lời

4

Do yêu cầu std::to_string().

Theo các tiểu bang tiêu chuẩn:

string to_string(int val);

string to_string(unsigned val);

string to_string(long val);

string to_string(unsigned long val);

string to_string(long long val);

string to_string(unsigned long long val);

string to_string(float val);

string to_string(double val);

string to_string(long double val);

Returns: Mỗi hàm trả một đối tượng chuỗi giữ đại diện nhân vật về giá trị của đối số của nó mà có thể được tạo ra bởi gọi sprintf (buf, fmt, val) với định dạng thông số là "% d", "% u", "% ld", "% lu", "% lld", "% llu", "% f", "% f" hoặc "% Lf", tương ứng, trong đó buf chỉ định bộ đệm ký tự bên trong đủ kích thước.

Viết chức năng mẫu có thể xác định thông số cần được sử dụng cho std::sprintf làm cho mọi thứ phức tạp không cần thiết.

3

Chỉ muốn thêm vào Gill Bates answer những gì tôi tìm thấy trong this proposal (nhờ @DAle cho liên kết).

Đề xuất về cách thêm phương thức chung to_string. Họ đang nói về khóa học về một phương pháp chung chung thực sự, nhưng nguyên tắc sẽ giống như của tôi gần như ngây thơ gần như một: dưới mui xe một dòng được sử dụng để có được một chuỗi từ bất kỳ đối tượng có thể được streamed.

Như đề xuất được đưa ra sau C++ 11, thêm một phương pháp như vậy sẽ có tác động đến trong phần "Tác động đến các tiêu chuẩn" hiện to_string và họ viết:

[...] Các chức năng cũ và mới có thể cùng tồn tại, dựa trên độ phân giải quá tải để thích phiên bản không có sẵn (hiện có) trong trường hợp loại đối số phù hợp . Tuy nhiên, một vấn đề tương thích có thể phát sinh trong trường hợp của một số loại đối số riêng biệt nhưng ngầm mui trần:

to_string(0);  // before: calls to_string(int), now: calls to_string(int) 
to_string(false); // before: calls to_string(int), now: calls to_string<bool>(bool&&) 
to_string('0'); // before: calls to_string(int), now: calls to_string<char>(char&&) 

Trong khi hiệu quả là giống hệt nhau trong hai trường hợp đầu tiên (kết quả là luôn "0"), trong cuối cùng một kết quả sẽ thay đổi từ "48" (giả định mã hóa ASCII) thành "0". Có một số cách để xử lý các trường hợp chuyên môn có vấn đề với như sau:

Và sau đó liệt kê một số tùy chọn (bao gồm bỏ qua vấn đề) trong đó không ai thực sự thỏa mãn. Imho một điều đáng tiếc là to_string vì nó được biến thành tiêu chuẩn ngay từ đầu. Mặt khác, Gill Bates trả lời cho một lý do chính đáng tại sao nó không được thực hiện chung từ đầu (nếu nó được cho là để tạo ra chuỗi như thể sprintf đã được sử dụng nó không phải là tầm thường, có thể không thể, nói chung).

Các vấn đề liên quan