Я хотел бы использовать std::bitset::all
но, к сожалению, мой компилятор до C ++ 11. Я знаю, что мог бы подражать функциональности, проверяя в цикле, все ли биты моего std::bitset
установлены.
например.,
template<std::size_t N>
bool
all(std::bitset<N> const &bs) {
int hits(0), sz(bs.size());
for(int i(0); i < sz; ++i) {
hits += bs[i];
}
return hits == sz;
}
Есть ли более правильная реализация std::bitset::all
заменить устаревшие компиляторы C ++ 11, чем тот, который показан выше.
Просто проверьте, если count
равно size
:
template<size_t N>
bool all_set(const std::bitset<N>& b) {
return b.count() == b.size();
}
Если вы хотите избежать цикла, но не заботитесь о максимальной производительности, вы можете сравнить count
против size
(т.е. проверить, равно ли количество установленных битов числу битов):
template<std::size_t N>
bool all(std::bitset<N> const &bs) {
return bs.count() == bs.size();
}
Недостатком (но то же самое с другими решениями, не относящимися к циклам, а также с вашей реализацией с циклом) является то, что он не остановится рано, когда первый бит не установлен. Если вы хотите воспользоваться этим, измените ваш цикл, чтобы выйти рано (и, кстати, вам не нужно sz
как есть N
):
template<std::size_t N>
bool all(std::bitset<N> const &bs) {
for (int i = 0; i < N; ++i)
if (!bs[i]) return false;
return true;
}
Глупый путь был бы
(~bs).none();
(глупо, потому что operator~
возвращает временный).
Вы могли бы использовать bs.count() == bs.size()
,
Другой способ — использовать метапрограммирование шаблона и развернуть биты битового поля, как показано в примере ниже:
template<std::size_t N, int M>
struct bitset_all_helper {
static bool check(std::bitset<N> const &bs) { return bs[M] && bitset_all_helper<N, M - 1>::check(bs); }
};
template<std::size_t N>
struct bitset_all_helper<N, 0> {
static bool check(std::bitset<N> const &bs) { return bs[0]; }
};
template<std::size_t N>
bool bitset_all(std::bitset<N> const &bs) { return bitset_all_helper<N, N - 1>::check(bs); }