Я пытаюсь написать шаблонный класс C ++, который содержит массив битов (в качестве переменной-члена). Размер битового массива известен во время компиляции, поэтому я бы очень хотел, чтобы он был std::bitset
, но у меня возникают трудности с написанием operator[]
функция к задавать биты.
Например, я хотел бы, чтобы мой класс начал что-то вроде этого:
template<size_t N>
class bitvector
{
public:
bool operator[](size_t i) const { return bits[i]; }
bool& operator[](size_t i) { return bits[i]; }
private:
std::bitset<N> bits;
};
Геттер работает хорошо. Проблема в том, что std::bitset::operator[]
Функция setter возвращает std::bitset::reference
(не bool&
) которая сама по себе является шаблонной. Я не слишком опытен с шаблонами, но следующая попытка не удалась:
template<size_t K>
std::bitset<K>::reference operator[](size_t i) { return bits[i]; }
со следующей ошибкой need 'typename' before 'std::bitset<K>::reference' because 'std::bitset<K>' is a dependent scope
, Я попробовал поискать в Google, но безрезультатно.
Является std::bitset
подходящий инструмент для этой задачи? Если так, как я могу написать функцию установки? Если нет, что я могу использовать вместо этого? (Я все еще хотел бы, чтобы это было фактически сохранено как биты, и std::vector<bool>
кажется не совсем правильным, так как я хочу, чтобы размер массива был строго фиксирован во время компиляции).
Вы можете просто вернуть std::bitset<N>::reference
следующее:
template<size_t N>
class bitvector
{
public:
bool operator[](size_t i) const { return bits[i]; }
typename std::bitset<N>::reference operator[](size_t i) { return bits[i]; }
private:
std::bitset<N> bits;
};
Там нет необходимости иметь дополнительный template<size_t K>
поскольку вы все еще можете получить доступ к исходному параметру шаблона N, и ни при каких обстоятельствах вы не захотите, чтобы N и K отличались.
Вам нужно typename
перед возвращаемым типом функции, чтобы сообщить компилятору ::reference
это тип, а не значение.
Например:
struct Foo{
typedef int reference;
};
struct Bar{
static int reference;
};
Вот Foo::reference
это тип, но Bar::reference
переменная, без typename
перед возвращаемым типом компилятор будет жаловаться, так как это может быть std::bitset<N>::reference
переменная (Компилятор должен располагать всей информацией, которая ему необходима для определения того, что это не значение, но по какой-то причине это требуется в любом случае).
Других решений пока нет …