WedX - журнал о программировании и компьютерных науках

std::vector‹bool› только с одним истинным элементом

Мне нужен std::vector<bool>, в котором только один элемент может быть истинным позже в программе. Моя попытка была (в цикле for)

BOOST_FOREACH( bool b, boolvector)
{
    b = false;
}
boolvector[j] = true;

Но когда это выполняется, элементы не сбрасываются в false при выполнении BOOST_FOREACH (функция библиотеки boost для более удобного повторения через контейнеры (см. документация по ускорению).

P.S.: Я знаю, что std::vector не работает, но этого должно быть достаточно.


  • I know that std::vector is a broken thing Так ли это? 26.07.2013
  • @ Nbr44 std::vector<bool> не является экземпляром std::vector<T> с T=bool. Это такая специализация, что каждый bool занимает только 1 бит. Это означает, что он не дает вам ссылки на содержащиеся bool, он дает вам прокси-объекты. По сути, он ведет себя не так, как другие экземпляры std::vector, и это широко считается ошибкой. Сломан с точки зрения дизайна, а не с технической точки зрения. 26.07.2013
  • Это похоже на объявление функции, где bool b вызывается по значению, а не по ссылке 26.07.2013
  • @BoBTFish Понятно. Вероятно, формулировка этого предложения была не совсем ясной. 26.07.2013
  • Я думаю, вы могли бы использовать std::bitset (или boost::dynamic_bitset) вместо этого. Вы пробовали? 26.07.2013
  • Нет, я не нашел, но я нашел другое (довольно простое) решение, используя итераторы с циклом for. 26.07.2013
  • Я предлагаю заменить вектор индексом истинного элемента. 04.12.2016

Ответы:


1

Я попробую это через несколько минут, но я подозреваю, что вы хотите

BOOST_FOREACH(std::vector<bool>::reference b, boolvector)
{
    b = false;
}

std::vector<bool>, как вы говорите, "сломан", и разыменование итератора не дает вам хорошую удобную ссылку, а дает вам некий прокси-объект: https://en.cppreference.com/w/cpp/container/vector_bool

Изменить: Да, это работает:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>

#include <boost/foreach.hpp>

void print (const std::vector<bool>& bv)
{
    std::cout << std::boolalpha;
    for (auto it = std::begin(bv); it != std::end(bv); ++it)
        std::cout << *it << ' ';
    std::cout << '\n';
}


int main()
{
    std::vector<bool> boolvector {true, false, true, false};
    print(boolvector);

    BOOST_FOREACH(std::vector<bool>::reference b, boolvector)
    {
        b = false;
    }

    print(boolvector);
}

Отпечатки:

$ ./a.out 
true false true false 
false false false false 

Этот:

BOOST_FOREACH(auto b, boolvector)

тоже работает, но

BOOST_FOREACH(auto& b, boolvector)

нет (не удается скомпилировать из-за не-const ссылки на временную).

Однако, как указывает Наваз, если у вас есть поддержка С++ 11, просто полностью откажитесь от BOOST_FOREACH и напишите:

for (auto b : boolvector)

Намного более поздняя правка:

Я не знаю, как я пропустил это в первую очередь, но похоже, что правильным решением здесь является использование assign:

b.assign(b.size(), false);
b[i] = true;
26.07.2013
  • Да, я вижу ошибку, которую я сделал сейчас. Но разве нельзя также получить ссылку на один бит? 26.07.2013
  • @BoBTFish: Да, ты прав. auto b работает. 26.07.2013
  • Кстати, если вы используете auto, зачем тогда использовать BOOST_FOREACH? Вы можете использовать for на основе диапазона. ;-) +1 26.07.2013
  • @Наваз Точно. Я предполагал отсутствие С++ 11 в реальном коде, поэтому в первую очередь использовал BOOST_FOREACH. Я использовал его в своем примере для удобства и упомянул auto из-за комментариев к уже удаленному ответу. 26.07.2013
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]