스토리텔링 개발자

[Effective STL] 18. vector<bool> 주의 본문

개발/Effective STL

[Effective STL] 18. vector<bool> 주의

김디트 2024. 11. 27. 10:50
728x90

항목 18. vector<bool> 보기를 돌같이 하자

 

 

 

vector<bool>의 문제점
  1. STL 컨테이너가 아니다.
  2. bool을 담고 있지도 않다.

 

 

비트(가짜 bool)로 구현되는 vector<bool>
  • STL 컨테이너의 조건
    • c가 타입 T의 객체를 담는 컨테이너라면 c에서 operator[]가 지원되어야 한다.
T* p = &c[0]; // 이런 코드가 동작해야 한다.
// 하지만, vector<bool>은 실제로 bool이 들어있지 않은 가짜 컨테이너라서
// 아래의 코드는 동작하지 않는다.
vector<bool> v;
bool* pb = &v[0];
  • vector<bool>은 공간을 줄이려고 bool을 압축시킨 데이터 표현 방식을 사용하기 때문이다.
  • 대개의 컴파일러는 bool을 하나의 비트로 구현하곤 한다.(가짜 bool값)
  • 하지만 비트필드는 참조자나 포인터로 만들 수 없다..
  • 그러므로 vector<T>::operator[]의 반환 타입(T&)을 만족시킬 수 없는 것이다.

 

 

 

프록시 객체(proxy object)로 vector<T>::operator[] 구현하기
  • 프록시 객체(MEC++ 항목 30 참조)
template<typename Allocator>
vector<bool, Allocator>
{
public:
    class reference { ... }; // 프록시 객체
    
    reference operator[](size_type n); // 프록시 객체를 리턴하는 operator[]
    ...
}

// 그러므로 아래 코드를 다시 보면 문제가 명확해진다.
vector<bool> v;
bool* pb = &v[0]; // vector<bool>::reference*을 bool*로 암시적 변환을 제공하지 않으므로

 

 

 

vector<bool> 같은 컨테이너가 필요할 때
  1. deque<bool>을 사용한다.
    • vector가 할 수 있는 거의 모든 것을 할 수 있다.
    • 진짜 bool을 저장하는 STL 컨테인터이다.
    • 물론 덱은 연속 메모리가 아니므로 bool 배열을 받는 C API에 넘길 때는 문제가 있다.
      • 허나 이 문제는 vector<bool>도 불가능하다.
      • 즉 항목 16 방법은 vector<bool>에는 통하지 않는다.(항목 16 참조)
  2. bitset을 사용한다.
    • bitset은 STL 컨테이너는 아니지만, 표준 C++ 라이브러리에 속한다.
    • bitset의 크기는 컴파일 타임에 고정되므로 런타임에 삽입 제거는 할 수 없다.
    • STL이 아니므로 반복자도 지원하지 않는다.
    • 하지만 명확하게 비트를 사용함을 보여주며, 비트 조작에 관련된 편리한 멤버 함수를 지원한다.

 

 

 

vector<bool>은 표준안에 속하며, STL 컨테이너의 요구사항을 '거의' 모두 만족한다
  • 요구사항을 모두 만족하지도 못하면서 왜 표준안에 속하는 걸까?
  • 프록시 객체를 사용해 STL을 구현하는 실험
    • STL에서 내부 요소를 프록시를 통해 엑세스할 수 있는 방법을 보여주기 위한 본보기로 쓰기로 했다고 한다..
    • 하지만, 결과적으로는 프록시 기반 컨테이너로는 STL 컨테이너의 요구사항을 모두 만족시킬 수 없었다.
728x90
Comments