C ++ предел неподписанного int через шаблон - PullRequest
6 голосов
/ 25 января 2012

Я использую шаблон для преобразования целочисленных типов в строковое представление их двоичных значений. Я использовал следующее:

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

Работает для int, но не компилируется с неподписанным 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

Не могли бы вы объяснить, почему?

EDIT:

Да, я использую VS2010

Ответы [ 3 ]

4 голосов
/ 25 января 2012

Не ваш вызов ToBinary является неоднозначным, это вызов конструктора набора битов со значением без знака. К сожалению, это ошибка VC ++: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

Редактировать - Обходной путь:

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 голосов
/ 25 января 2012

Если вы посмотрите на стандарт (FDIS n3290), то увидите, что std::bitset имеет несколько конструкторов:

Сначала есть это:

20.5.1 конструкторы битовых наборов [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

Эффекты: Создает объект класса bitset, инициализируя положение первых M бит в соответствующих битовых значениях в val. М является меньшее из N и количество бит в представлении значения (3.9) неподписанных долго-долго. Если M

Кроме того, есть еще один, который, я подозреваю, мог бы вызвать неоднозначность, когда вы называете это с помощью 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’));

Эффекты: Создает объект класса bitset, как если бы он был

bitset( n == basic_string<charT>::npos ? basic_string<charT>(str) :
basic_string<charT>(str, n), 0, n, zero, one)
0 голосов
/ 25 января 2012

Вы используете VC10?Уже сообщается о проблеме: Microsoft connect. Также я могу предположить, что вы могли бы исправить это, приведя тип к int, если он 32-битный, например:

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

Это также можно сделать внутри метода, если это необходимо.Однако результат переосмысления больше не должен использоваться для арифметики.;)

Работает нормально, как обходной путь для меня (но выглядит довольно некрасиво)

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";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...