Как написать шаблон std :: bitset, который работает на 32 и 64-битных - PullRequest
8 голосов
/ 14 марта 2009

Рассмотрим следующий код

template<unsigned int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main()
{
    bitset<8> bar;
    foo(bar);
    return 0;
}

g ++ жалуется на это в 64-битной версии, потому что <8> интерпретируется как unsigned long int, которое не совсем соответствует шаблону. Если я поменяю шаблон на unsigned long int, то 32-битные компиляции будут жаловаться.

Очевидно, один из способов исправить это - изменить битовый набор <8> на битовый набор <8ul>, но есть ли способ переписать часть template , чтобы она работала с любой интерпретацией по умолчанию числового литерала есть?

Ответы [ 3 ]

8 голосов
/ 14 марта 2009

Проблема не в том, пишете ли вы 8u или 8. Проблема связана с типом параметра шаблона вашего функционального шаблона. Его тип должен соответствовать типу, используемому в объявлении std::bitset. Это size_t в соответствии со Стандартом (раздел 23.3.5)

namespace std {
    template<size_t N> class bitset {
    public:
    // bit reference:
        ...

Исключением являются размеры массива, для которых вы можете использовать любой целочисленный тип (даже bool - тогда единственный допустимый размер - 1, конечно):

// better size_t (non-negative), but other types work too
template<int N> void f(char(&)[N]);

Но в других случаях типы должны совпадать. Обратите внимание, что это верно только для автоматически выводимых аргументов шаблона, но не для явно заданных. Причина в том, что для выводимых компилятор пытается выяснить наилучшее соответствие между фактическими аргументами шаблона и тем, что он вывел из обращения к нему. Многие иначе неявные преобразования запрещены. У вас есть полный диапазон доступных преобразований, если вы явно укажете аргумент (игнорируя решение использовать size_t сейчас, чтобы выразить свою точку зрения)

template<int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main() {
    bitset<8> bar;
    foo<8>(bar); // no deduction, but full range of conversions
}
3 голосов
/ 14 марта 2009

Используйте size_t. Так скажи хотя бы MSDN.

0 голосов
/ 14 марта 2009

числовой литерал должен интерпретироваться как int независимо от платформы

...