2012-01-25 23 views
6

Tôi đang sử dụng mẫu để chuyển đổi các loại tích phân thành một chuỗi biểu diễn các giá trị nhị phân của chúng. Tôi sử dụng như sau:Giới hạn C++ của mẫu không dấu int thông qua mẫu

template<typename T> 
std::string ToBinary(const T& value) 
{ 
    const std::bitset<std::numeric_limits<T>::digits + 1> bs(value); 
    const std::string s(bs.to_string()); 

    return s; 
} 

Nó hoạt động cho int nhưng không biên dịch với unsigned int:

unsigned int buffer_u[10]; 
int buffer_i[10]; 
... 
ToBinary(buffer_i[1]); //compile and works 
ToBinary(buffer_u[1]); //doesn't compile -- ambiguous overload 

Ông có thể giải thích tại sao?

EDIT:

Vâng, tôi đang sử dụng VS2010

+0

Bạn đang sử dụng trình biên dịch nào? Điều này: 'const std :: bitset <33> bs (buffer_u [1]);' tạo ra lỗi quá tải không rõ ràng trên VC2010 nhưng biên dịch tốt với g ++ 3.4.6. – hmjd

Trả lời

4

Không gọi ToBinary của bạn là mơ hồ, nó gọi constructor của bitset với một giá trị unsigned. Thật không may đây là một VC++ Bug: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

Edit - Cách giải quyết:

template<> 
std::string ToBinary<unsigned int>(const unsigned int& value) 
{ 
    const std::bitset<std::numeric_limits<unsigned int>::digits> bs(static_cast<unsigned long long>(value)); 
    return bs.to_string(); 
} 
+0

cảm ơn. Bạn có thể đề xuất bất kỳ cách giải quyết nào không? – Heisenbug

+0

chuyên mẫu cho int không dấu và sử dụng unsigned long long như đề xuất trong giải pháp và cắt kết quả trở lại thành tiêu chuẩn: số hoặc số đã sử dụng nó làm N cho bitet KasF

0

Bạn đang sử dụng VC10? Đã có một vấn đề báo cáo: Microsoft connect. Ngoài ra tôi đoán rằng bạn có thể sửa chữa nó bằng cách đúc kiểu int nếu nó là 32 bit, như thế này:

string s = ToBinary(*reinterpret_cast<int*>(&buffer_u[1])); 

này có thể được thực hiện bên trong của phương pháp là tốt nếu cần thiết. Kết quả của việc diễn giải lại không nên được sử dụng cho arithmetics nữa, mặc dù. ;)

Hoạt động tốt như cách giải quyết đối với tôi (nhưng trông khá xấu xí)

template<typename T> 
std::string ToBinary(const T& value) 
{ 
    switch (sizeof(T)) 
    { 
    case 8: 
     return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const long*>(&value)).to_string(); 
    case 4: 
     return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const int*>(&value)).to_string(); 
    case 2: 
     return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const short*>(&value)).to_string(); 
    case 1: 
     return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const char*>(&value)).to_string(); 
    } 
    return "n/a"; 
} 
+0

nó biên dịch nhưng nó không 't làm việc (tăng ngoại lệ vi phạm truy cập) – Heisenbug

+0

Thật sao? Hoạt động hoàn toàn tốt cho tôi - thay vì toán tử chỉ mục, bạn cũng có thể sử dụng '* reinterpret_cast (buffer_u + 1)'. Tôi cập nhật câu trả lời ở trên bao gồm cả một ToBinary thay đổi. – Coder02

0

Nếu bạn nhìn vào các tiêu chuẩn (FDI n3290), sau đó bạn thấy rằng std::bitset có nhiều nhà xây dựng:

Đầu tiên có một điều này:

20.5.1 constructors bitset [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

Effects: Tạo thời đối tượng của lớp bitset, khởi tạo vị trí M bit đầu tiên để các giá trị bit tương ứng trong val. M là nhỏ hơn của N và số bit trong biểu diễn giá trị (3.9) không có dấu dài. Nếu M < N, các vị trí bit còn lại là được khởi tạo về 0.

Sau đó, cũng là một trong những này, mà tôi nghi ngờ có thể là có thể gây ra những thứ để trở thành ambigious, khi bạn gọi nó với unsigned int

template <class charT> 
explicit bitset(
const charT* str, 
typename basic_string<charT>::size_type n = basic_string<charT>::npos, 
charT zero = charT(’0’), charT one = charT(’1’)); 

Effects: Tạo thời đối tượng của lớp bitset như thể by

bitset(n == basic_string<charT>::npos ? basic_string<charT>(str) : 
basic_string<charT>(str, n), 0, n, zero, one) 
+0

Không, một số nguyên không bao giờ tự nguyện chuyển đổi thành con trỏ, bạn phải ép buộc nó bằng một dàn diễn viên. – Xeo

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