2012-12-14 28 views
5

Hiện nay, tôi có một hàm template như thế này có thể chuyển đổi một vector thành một string (chỉ là một chuỗi tự nhiên, tách các phần tử với một dấu phẩy):Cách tốt hơn để thực thi mẫu này?

//the type T must be passable into std::to_string 
template<typename T> 
std::string vec_to_str(const std::vector<T> &vec); 

Như bạn có thể thấy, đây chỉ dành cho những vectơ mà các thành phần có thể được chuyển vào built-in std::to_string chức năng (như int, double, vv)

Is it coi là một thực hành tốt để ghi lại với ý kiến ​​các phép T? Nếu không, tôi nên làm gì? Có thể thực thi điều này theo cách tốt hơn không?

+0

Tất nhiên, bạn thậm chí có thể chọn để ghi lại với ý kiến ​​và thực thi với một kỹ thuật SFINAE. – aschepler

Trả lời

2

Kể từ std::to_string là một tính năng C++ 11, tôi đoán bạn có thể mở cửa cho một giải pháp C++ 11. Trong trường hợp này, bạn có thể sử dụng các kiểu trả về trailing một cách sfinae:

template <typename T> 
auto vec_to_str(const std::vector<T>& vec) -> decltype(std::to_string(std::declval<T>())); 

đó sẽ thất bại trong việc thay thế (và loại bỏ tình trạng quá tải đó) nếu giá trị kiểu không làm việc cho to_string. Tuy nhiên, đó không nhất thiết phải là cách dễ chịu nhất để ghi lại và thực thi quy tắc. Có lẽ có một phiên bản trước C++ 11 của thủ thuật Sfinae ở trên, nhưng nó sẽ không đẹp hơn chút nào.

Nói chung, tôi có thể nói rằng bạn chỉ cần ghi tài liệu trong nhận xét (có thể với thẻ doxygen, như \tparam). Bạn có thể sử dụng một cơ chế kiểm tra khái niệm, theo kiểu Boost.Concept-Check nếu bạn muốn. Là một lưu ý phụ, đối với trường hợp cụ thể này, tôi có thể khuyên bạn nên dựa vào std::ostreamoperator << thay vì chức năng to_string, vì có nhiều khả năng là các loại tùy chỉnh (ví dụ: vector 2D hoặc thứ gì đó) sẽ được trang bị với quá tải để xuất ra luồng.

0

Cho đến concepts đến, bạn có thể sử dụng decltype với một tham số kiểu nặc danh:

template<typename T, 
    typename = decltype(std::to_string(std::declval<T>()))> 
std::string vec_to_str(const std::vector<T> &vec); 
4

Với static_assert và một số biểu hiện SFINAE, bạn có thể có một thông báo lỗi thời gian biên dịch tốt đẹp:

template<typename T> 
constexpr auto allowed(int) -> decltype(std::to_string(std::declval<T>()), bool()) 
{ 
    return true; 
} 

template<typename> 
constexpr bool allowed(...) 
{ 
    return false; 
} 

template<typename T> 
std::string vec_to_str(const std::vector<T>& vec) 
{ 
    static_assert(allowed<T>(0), "Invalid value type."); 
    return ""; 
} 

struct foo {}; 

int main() 
{ 
    std::vector<int> v_int; 
    vec_to_str(v_int); 

    std::vector<foo> v_double; 
    vec_to_str(v_double);  // static_assert fires here 
} 
Các vấn đề liên quan