2012-07-03 48 views
9

Trong một mẫu hàm đó trông như thế này:Làm chức năng mẫu tham số unsigned trong C++ 11

template<typename T> constexpr T foo(T a, T b) { return /*recursive call*/; } 

Tôi nhận được một cảnh báo về so sánh ký vs unsigned (do so sánh với sizeof) mà tôi muốn muốn loại bỏ.

Về mặt lý thuyết, người ta sẽ cần một cái gì đó như thế này:

template<typename T> constexpr T foo(T a, unsigned T b) { ... } 
    or 
template<typename T> constexpr T foo(T a, std::make_unsigned<T>::type b) { ... } 

Thật không may, phiên bản đầu tiên không phải là hợp lệ C++, và phiên bản thứ hai phá vỡ build vì T không phải là một loại trình độ khi trình biên dịch thấy make_unsigned.

Có giải pháp nào thực sự hoạt động không?

(NB: Bằng cách nào đó liên quan đến/gần giống như Get the signed/unsigned variant of an integer template parameter without explicit traits, mặc dù chức năng chứ không phải là lớp (vì vậy không typedefs), đặc điểm hoặc bất kỳ tính năng của C++ 11 rõ ràng chào đón, và giải pháp làm việc (ví dụ khôngmake_unsigned<T>) ưa thích .)

Trả lời

10

bạn quên một 'typename'

template<typename T> 
constexpr T foo(T a, typename std::make_unsigned<T>::type b) { ... } 

Trong C++ 14 bạn sẽ có thể viết

template<typename T> 
constexpr T foo(T a, std::make_unsigned_t<T> b) { ... } 

Hoặc bạn có thể tự mình thực hiện điều này trong C++ 11:

template<typename T> 
using make_unsigned_t = typename std::make_unsigned<T>::type; 
+0

Thật vậy! Cảm ơn bạn rất nhiều :) – Damon

+0

Tôi đang đối mặt với một vấn đề tương tự cho C++ 03. Tôi muốn hai mẫu: một cho 'mẫu ' và class 'template '. Tôi cần phải kiểm tra nếu một diễn viên có thể được làm từ 'T' thành' U'. Có một giải pháp trong thế giới C++ 03? (Điều này có đảm bảo một câu hỏi mới)? – jww

+1

@jww yeah, tôi muốn nói rằng đó phải là câu hỏi của riêng nó. – bames53

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