Альтернатива вектору <bool>

Поскольку (надо надеяться), все мы знаем, vector<bool> полностью повреждается и не может рассматриваться как массив C. Что лучший способ состоит в том, чтобы получить эту функциональность? До сих пор идеи, о которых я думал:

  • Используйте a vector<char> вместо этого, или
  • Используйте класс обертки и имейте vector<bool_wrapper>

Как делают Вас, парни решают эту проблему? Мне нужно c_array() функциональность.

Как вопрос о стороне, если мне не нужно c_array() метод, что лучший способ состоит в том, чтобы приблизиться к этой проблеме, если мне нужен произвольный доступ? Я должен использовать двухстороннюю очередь или что-то еще?

Править:

  • Мне действительно нужна динамическая калибровка.
  • Для тех, кто не знает, vector<bool> специализирован так, чтобы каждый bool берет 1 бит. Таким образом Вы не можете преобразовать его в массив C-стиля.
  • Я предполагаю, что "обертка" является чем-то вроде неправильного употребления. Я думал что-то вроде этого:

Конечно, затем я должен читать в a my_bool из-за возможных проблем выравнивания :(

struct my_bool
{
    bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
86
задан CoffeeTableEspresso 25 July 2019 в 06:24
поделиться

5 ответов

Используйте std::deque , если Вам не нужны массив, да.

Иначе используют альтернативу vector, который не специализируется на bool, такие как тот в Контейнер Повышения .

38
ответ дан Daniel Earwicker 24 November 2019 в 08:06
поделиться

Это - интересная проблема.

, Если Вам нужно в том, что было бы станд.:: вектор, если бы это не было специализировано, тогда возможно, что-то как этот, хорошо работал бы с Вашим случаем:

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

class Bool
{
public:

    Bool(): m_value(){}
    Bool( bool value ) : m_value(value){}

    operator bool() const { return m_value;}

    // the following operators are to allow bool* b = &v[0]; (v is a vector here).
    bool* operator& () { return &m_value; }
const bool * const operator& () const { return &m_value; }

private:

    bool m_value;

};




int main()
{
    std::vector<Bool> working_solution(10, false);


    working_solution[5] = true;
    working_solution[7] = true;


    for( int i = 0; i < working_solution.size(); ++i )
    {
        std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::sort( working_solution.begin(), working_solution.end());
    std::cout<< "--- SORTED! ---" << std::endl;

    for( int i = 0; i < working_solution.size(); ++i )
    {
            bool* b = &working_solution[i]; // this works!

        std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::cin.get();
    return 0;
}

я попробовал это VC9, и это, кажется, хорошо работает. Идея класса Bool состоит в том, чтобы моделировать тип bool путем обеспечения того же поведения и размера (но не тот же тип). Почти вся работа сделана bool оператором и конструкторами копии по умолчанию здесь. Я добавил вид, чтобы быть уверенным, что он реагирует, как принято при использовании алгоритмов.

Не уверенный это удовлетворило бы всем случаям. Если бы это правильно для Ваших потребностей, это было бы меньше работы, чем перезапись подобного вектору класса...

20
ответ дан Klaim 24 November 2019 в 08:06
поделиться

Зависит от Ваших потребностей. Я пошел бы для также std::vector<unsigned char>. Writting обертка может быть прекрасной, если Вы только используете подмножество функциональности, еще это станет кошмаром.

17
ответ дан Daniel Earwicker 24 November 2019 в 08:06
поделиться

Рассмотрите использование vector< интервал>. Как только Вы заканчиваете компиляцию, и проверка типа, bool и интервал являются оба просто машинными словами (редактирование: по-видимому, это не всегда верно; но будет верно на многой архитектуре ПК). В тех случаях, где Вы хотите преобразовать без предупреждения, используйте "bool нечто =!! панель", которая преобразовывает нуль в ложь и ненулевой к истинному.

А vector< символ> или подобный использует меньше пространства, хотя это также имеет потенциал для взятия (очень маленькой) скорости, пораженной в некоторых обстоятельствах, потому что символы являются меньше, чем размер машинного слова. Это, я верю, главная причина, что bools реализованы с помощью ints вместо символов.

, Если Вы действительно хотите чистую семантику, мне также нравится предложение создания Вашего собственного булева класса - похож на bool, действует как bool, но дурачит шаблонную специализацию.

кроме того, добро пожаловать в клуб людей, которые хотят vector< bool> специализация, отброшенная из стандарта C++ (с bit_vector для замены его). Это - где все спокойные дети болтаются:).

5
ответ дан AHelps 24 November 2019 в 08:06
поделиться

Эта проблема уже была , обсудил на comp.lang.c ++. модерируемый. Предлагаемые решения:

  • Ваше собственное средство выделения (на основе std::allocator) и собственная векторная специализация;
  • использование std::deque (как рано рекомендовался в одной из книг S. Mayers) - но это не для Ваших требований;
  • делают обертку POD bool;
  • использование что-то (char / int / и т.д.) с тем же размером как bool вместо этого bool;

Также рано я видел, что предложение для стандартного комитета - представляет макрос (что-то как STD_VECTOR_BOOL_SPECIAL) для запрещения этой специализации - но AFAIK это предложение не было реализовано в stl реализациях и не было утверждено.

кажется, что Ваша проблема не имеет никаких способов сделать это приятно... Возможно, в C++ 0x.

4
ответ дан Dev Null 24 November 2019 в 08:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: