2015-06-03 14 views
7

Trong một ví dụ với vector<int> someVectoristringstream someStringStream bạn có thể làm điều này:Làm thế nào để bạn sử dụng toán tử trích xuất (>>) với vectơ <bool>?

for (int i=0; i < someVector.size(); i++) { 
    someStringStream >> someVector[i]; 
} 

Tôi biết rằng vector<bool> là một thực hiện hiệu quả, và operator[] trả về một đối tượng tham khảo. Đối với mã này tôi nên sử dụng một chỉ mục chứ không phải là một trình lặp, chủ yếu là để dễ đọc. Hiện tại, tôi đang sử dụng điều này:

for (int i=0; i < someVector.size(); i++) { 
    bool temp; 
    someStringStream >> temp; 
    someVector[i] = temp; 
} 

Có cách nào trực tiếp hơn để thực hiện việc này không?

Trả lời

0

Nếu tất cả những gì bạn muốn là cùng một giao diện cho bool và các loại khác, thật dễ dàng để kết nối mọi thứ.

template <typename T> 
T read(std::istream& stream) 
{ 
    T value; 
    stream >> value; // TODO: guard against failure of extraction, e.g. throw an exception. 
    return value; 
} 

Tuy nhiên, việc sử dụng trực tiếp này yêu cầu bạn chỉ định loại.

for (int i=0; i < someIntVector.size(); i++) 
{ 
    someIntVector[i] = read<int>(someStringStream); 
} 

for (int i=0; i < someBoolVector.size(); i++) 
{ 
    someBoolVector[i] = read<bool>(someStringStream); 
} 

Nếu bạn sử dụng lại cho vectơ khác nhau, chỉ cần quấn nó một lần nữa:

template <typename T, typename A> 
void fillVectorFromStream(std::istream& stream, std::vector<T, A>& vector) 
{ 
    for (int i = 0; i < vector.size(); ++i) 
    { 
     vector[i] = read<T>(stream); 
    } 
} 

Do đó, việc sử dụng chỉ đơn giản là trở thành

fillVectorFromStream(streamOfBool, vectorOfBooleanValues); 
fillVectorFromStream(streamOfIntegers, vectorOfIntegers); 
+0

Điều này không an toàn. Nếu toán tử >> thất bại, thì "giá trị" sẽ không được khởi tạo. Hoặc trạng thái luồng phải được kiểm tra rõ ràng hoặc std :: ios_base :: failbit phải được ORED đối với ngoại lệ của luồng(). –

+1

@ArneVogel Điều này thay đổi trong C++ 11: nếu khai thác thất bại, số không được ghi vào giá trị (xem http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt). Tuy nhiên, tôi đồng ý rằng việc kiểm tra lỗi là cần thiết trong mã sản xuất. Tuy nhiên, có rất nhiều cách để làm điều đó. Nó không phải là phạm vi của câu hỏi để chọn một, imho. – stefan

5

Bạn có thể sử dụng std::copy hoặc các nhà xây dựng std::vector nhiều nếu bạn muốn tiêu thụ toàn bộ luồng:

std::stringstream ss("1 0 1 0"); 
std::vector<bool> vec; 
std::copy(std::istream_iterator<bool>(ss), {}, std::back_inserter(vec)); 

LIVE DEMO

std::stringstream ss("1 0 1 0"); 
std::vector<bool> vec(std::istream_iterator<bool>(ss), {}); 

LIVE DEMO

Bây giờ nhìn vào ví dụ mà bạn đăng lên và nếu bạn chắc chắn rằng kích thước std::vector của bạn là thích hợp, bạn có thể sử dụng std::generate như ví dụ dưới đây:

std::stringstream ss("1 0 1 0"); 
std::vector<bool> vec(4); 
std::generate(std::begin(vec), std::end(vec), [&ss](){ bool val; ss >> val; return val;}); 

LIVE DEMO

Các vấn đề liên quan