C ++ restriction unsigned int via pattern

I use a template to convert integral types to a string representation of their binary values. I used the following:

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; } 

It works for int, but does not compile with 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 

Could you explain why?

EDIT:

Yes, I am using VS2010

+6
source share
3 answers

Not your binary call is ambiguous, its a bit set constructor call with an unsigned value. Unfortunately, this is a VC ++ error: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

Edit - Workaround:

 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(); } 
+4
source

Are you using a VC10? There is already a problem: Microsoft connect. I would also suggest that you can fix this by exposing the int type if it is 32 bits, for example:

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

This can be done inside the method, if necessary. However, the result of reinterpretation should no longer be used for arithmetic .;)

Works well as a workaround for me (but looks pretty ugly)

 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
source

If you look at the standard (FDIS n3290), you will see that std::bitset has several constructors:

First, this one:

20.5.1 bitter constructors [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

Effects: Creates a class bit object, initializing the first M bits to the corresponding bit values ​​in val. M is less than N and the number of bits in the representation of the values ​​(3.9) of an unsigned long long. If M <N, the remaining bit positions are initialized to zero.

Then there is this one, which, I suspect, can lead to the situation becoming ambiguous when you call it using 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: Creates an object of the class bits, as if

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

Source: https://habr.com/ru/post/906843/


All Articles