2012-01-25 24 views
6

Estoy usando una plantilla para convertir los tipos integrales en una cadena de representación de sus valores binarios. He utilizado el siguiente:C++ límite de unsigned int a través de la plantilla

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

Funciona para int pero no compila con 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 

Podría explicar por qué?

EDIT:

Sí, estoy usando VS2010

+0

¿Qué compilador está utilizando? Esto: 'const std :: bitset <33> bs (buffer_u [1]);' produce un error de sobrecarga ambiguo en VC2010 pero compila bien con g ++ 3.4.6. – hmjd

Respuesta

4

No ToBinary su llamada es ambigua, es la llamada al constructor de bitset con un valor sin signo. Por desgracia, este es un VC++ Bug: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

Editar - Solución:

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

gracias. ¿Puedes sugerir alguna solución? – Heisenbug

+0

especialice la plantilla para unsigned int y use unsigned long long como se sugiere en la solución y recorte el resultado a std :: numeric_limits :: digits o úselo ya como N para el conjunto de bits KasF

0

¿Está utilizando VC10? Ya existe un problema informó: Microsoft connect. También supongo que usted podría ser capaz de solucionarlo mediante fundición del tipo a int si es de 32 bits, así:

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

Esto se puede hacer dentro de la método también si es necesario. Sin embargo, el resultado de la reinterpretación ya no se debe usar para aritmética. ;)

funciona bien como solución para mí (pero se ve bastante feo)

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

compila pero no lo hace no funciona (aumenta la excepción de violación de acceso) – Heisenbug

+0

¿De verdad? Funciona perfectamente bien para mí: en lugar de operador de índice, puede usar '* reinterpret_cast (buffer_u + 1)' también. Actualicé la respuesta anterior incluyendo un ToBinary cambiado. – Coder02

0

Si nos fijamos en la norma (FDIS n3290), entonces ver que std::bitset tiene varios constructores:

Primera hay ésta:

20.5.1 constructores BitSet [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

Efectos: Construye un objeto de bitset clase, inicializando los primeras posiciones de bit M a los valores de bit correspondientes de val. M es el más pequeño de N y el número de bits en la representación del valor (3.9) de longitud larga sin signo. Si M < N, las posiciones de bit restantes son inicializadas a cero.

Luego está también éste, y sospecho que podría ser podría causar que las cosas se vuelven ambigua, cuando se llama con 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’)); 

Efectos: Construye un objeto de bitset clase como si por

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

No, un número entero nunca se convierte voluntariamente en un puntero, debe forzarlo con un molde. – Xeo

Cuestiones relacionadas