2013-05-09 1 views
2

У меня есть следующий код, который в основном берет вектор и записывает его в файл, а затем открывает файл и записывает содержимое в другой вектор.Оператор >> не любит вектор <bool>?

#include <fstream> 
#include <iostream> 
#include <vector> 

using namespace std; 

int main() 
{ 
    vector<bool> q, p; 
//   ^^^^ 
    q.resize(5, 0); 
    q[0] = 1; 
    q[2] = 1; 
    q[4] = 1; 

    ofstream ofile("file.log"); 

    for (int i = 0; i<5; i++) 
     ofile <<q[i]<<" "; 

    ofile.close(); 

    ifstream ifile("file.log"); 

    p.resize(5); 

    int i = 0; 
//  vvvvvvvvvvvv 
    while(ifile>> p[i]) 
    { 
     cout <<i<<"\t"<<p[i]<<endl; 
     i++; 
    } 

    ifile.close(); 

    return 0; 
} 

То, что я заметил, что этот код компилируется и работает без проблем, когда вектор содержит двойной, Int и длинные тип данных, но выдает ошибку, если она изменяется на BOOL. Это сообщение об ошибке, которое я получаю:

../src/timeexample.cpp:31: error: no match for ‘operator>>’ in ‘ifile >> p.std::vector<bool, _Alloc>::operator[] [with _Alloc = std::allocator<bool>](((long unsigned int)i))’ 

Итак, кто-нибудь знает, почему это происходит?

Спасибо

+0

В коде, который вы отправили, нет 'vector '. – 2013-05-09 19:37:23

+0

Я считаю, что переменная bool имеет размер 1 бит. так что битдвиг ничего не сделает. Проверьте @Chris. Я ошибся, прочитав спецификацию как бит, когда он четко говорит о байте. – Nomad101

+4

@ Nomad101, переменные должны быть не менее одного байта. – chris

ответ

6

std::vector<bool> специализируется иметь эффективность использования пространства. operator[] не сможет вернуть адресную переменную, поэтому вместо этого он возвращает прокси-объект std::vector<bool>::reference. Просто введите его во временную переменную и передать его:

bool b; 
while (ifile >> b) { 
    p[i] = b; 
    cout <<i<<"\t"<<b<<endl; 
    i++; 
} 
+0

Спасибо, Крис. Это устраняет проблему. :) – ipluto

1

vector<bool> не то, что вы думаете. Это специализация std :: vector, которая оптимизирована для пространства, а не для операций над элементами, пытаясь уменьшить память bool, используя биты для представления значений bool. Когда используются биты, операторы потока больше не могут работать.

Se here для важных результатов оптимизации:

  • Хранилище не обязательно является массив значений BOOL, но реализация библиотеки может оптимизировать хранение так, чтобы каждое значение хранится в одной немного.
  • Элементы не построены с использованием объекта распределителя, но их значение непосредственно устанавливается на правильный бит во внутренней памяти.
  • Функция члена flip и новая подпись для обмена членами.
  • Специальный тип элемента, ссылка, класс, который обращается к отдельным битам во внутреннем хранилище контейнера с интерфейсом, который эмулирует ссылку bool. И наоборот, тип const const_reference равен простой bool.
  • Типы указателей и итераторов, используемые контейнером, не обязательно являются ни указателями, ни соответствующими итераторами, хотя они должны имитировать большую часть ожидаемого поведения.

Существует другая структура данных, которые вы можете использовать INT таким образом, если вы знаете, сколько bool ценности у вас есть во время компиляции: bitset

Это операторы потока определены, что и вы нацеливаясь на.

+0

Спасибо за подробное объяснение. У него определенно было что-то для меня, чтобы учиться. – ipluto

+0

@ipluto без проблем :) – tmaric

 Смежные вопросы

  • Нет связанных вопросов^_^