2013-06-16 26 views
16

C++ không có cách nào để lấy biểu diễn chuỗi của một enum. Người làm được việc này bằng cách viết các chức năng tùy chỉnh có chứa rất nhiều mã boilerplate aka
switch với case XYZ return "XYZ";Là ghi đè std :: to_string cho người dùng xác định enums cách thích hợp để cung cấp to_string cho người dùng xác định enums?

Điều đó tất nhiên đòi hỏi người sử dụng enum để biết tên của các chức năng tùy chỉnh.

Vì vậy, tôi nghĩ rằng tôi chỉ có thể thêm chuyên môn vào std::to_string để cho phép người dùng sử dụng to_string trên enums của tôi. Một cái gì đó như thế này:

// 
#include <iostream> 
#include <string> 
#include <cassert> 
#define TEST 
class Car 
{ 
public: 
    enum class Color 
    { 
     Red, 
     Blue, 
     White 
    }; 
}; 
#ifdef TEST 
#include <string> 
namespace std 
{ 
    std::string to_string (Car::Color c) 
    { 
     switch (c) 
     { 
     case Car::Color::Red: 
      return "Red"; 
     case Car::Color::Blue: 
      return "Blue"; 
     case Car::Color::White: 
      return "White"; 
     default: 
      { 
       assert(0); 
       return ""; 
      } 
     } 
    } 

} 
#endif 
int main() 
{ 
    std::cout << std::to_string(Car::Color::White) << std::endl; 

} 

Có vấn đề gì với giải pháp này không?

+4

Tôi không cho phép chức năng std quá tải được phép, chỉ có các mẫu chuyên biệt. – chris

+0

Hai điều: Tôi sẽ kiểm tra việc sử dụng '#define str (x) # x' (và kết hợp' #define glue (a, b) a ## b') để xem có phù hợp với nhu cầu của bạn với ít bản mẫu không . Chỉ cần chắc chắn để bọc nó trong một chức năng cho an toàn loại, và để '# undef' nó ngay sau khi bạn đã hoàn tất. Thứ hai, và ít quan trọng hơn, là bạn đã quên 'break;' s trong switch của bạn - có thể đưa ra một lý do không sử dụng nó nếu bạn không cảm thấy siêu đơn vị testy. – FizzixNerd

Trả lời

22

Đó không phải là "ghi đè" (áp dụng cho các chức năng virtual) và bạn chưa thêm "chuyên môn" (áp dụng cho mẫu), bạn đã thêm quá tải, bổ sung một tuyên bố và định nghĩa về chức năng để không gian tên std và đó là cấm:

17.6.4.2.1 Namespace std [namespace.std]
hành vi của một chương trình C++ là undefined nếu nó thêm tuyên bố hoặc định nghĩa để không gian tên std hoặc một không gian tên trong không gian tên std trừ khi được chỉ định khác. Chương trình có thể thêm chuyên môn mẫu cho bất kỳ mẫu thư viện chuẩn nào vào không gian tên chỉ khi khai báo phụ thuộc vào loại do người dùng xác định và chuyên môn đáp ứng các yêu cầu thư viện chuẩn cho mẫu ban đầu và không bị cấm rõ ràng.

Một giải pháp tốt hơn là quá tải nó trong không gian tên của riêng bạn và gọi to_string(c) thay vì std::to_string(c). Điều đó sẽ tìm thấy đúng chức năng và bạn không cần phải thêm bất kỳ thứ gì vào std

+0

chờ đợi, im nhầm làm thế nào để u có nghĩa là "mà thêm một tuyên bố và định nghĩa của một chức năng mới để không gian tên std" ... to_string tồn tại trong std, phải không? Bạn có xem xét params một phần của chức năng vì vậy đó là lý do tại sao bạn gọi nó là mới? – NoSenseEtAl

+0

Vâng, đó là một chức năng mới, phải không? Nó không có ở đó trước đây. Nó không phải là một _name_ mới nhưng bạn đang định nghĩa một hàm mới. Hàm 'std :: to_string (int)' là một hàm khác với 'std :: to_string (double)' và một hàm khác với 'std :: to_string (Car :: Color)' –

+3

Tiêu chuẩn C++ xem xét các kiểu tham số của hàm quá, không chỉ là tôi: ** 1.3.17 [defns.signature] chữ ký ** tên, danh sách kiểu tham số (8.3.5), và khoảng trống kèm theo (nếu có) –

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