44. std::vector<bool> 특수화와 프록시 참조
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C++
// [주제] std::vector<bool> 특수화
//
// [과제]
// 1. 아래 프로그램의 출력을 예측하시오. 컴파일 오류가 나는 줄이 있다면 어느 줄이고 왜인지
// 설명하시오. (지금은 해당 줄이 주석 처리되어 있다.)
// 2. sizeof(bool) 이 1인 플랫폼에서 vb 와 vc 의 메모리 사용량이 왜 다른지 설명하시오.
// 3. printFirst 와 flipFirst 안의 auto 가 각각 어떤 타입으로 추론되는지 두 컨테이너에 대해
// 답하시오. 두 함수에서 결과가 갈리는가? 갈린다면(또는 갈리지 않는다면) 그 이유는?
// 4. 표준 컨테이너의 어떤 일반 규약이 vector<bool> 에서 성립하지 않는지 열거하고,
// 그것이 제네릭 코드에 어떤 영향을 주는지 설명하시오.
//
// 게임서버 맥락: 플레이어별 퀘스트 완료 플래그, AoI 가시성 마스크, 스킬 슬롯 사용 여부처럼
// 대량의 불리언을 다루는 자료구조에서 이 특수화가 실제로 문제를 일으킨다.
#include <cstdio>
#include <typeinfo>
#include <vector>
template <class Container>
void printFirst(const Container& c) {
auto first = c[0];
std::printf("first=%d, sizeof(elem-proxy)=%zu\n",
static_cast<int>(first), sizeof(first));
}
template <class Container>
void flipFirst(Container& c) {
auto x = c[0];
x = true; // x 를 통해 컨테이너를 바꾸려는 시도
}
int main() {
std::vector<bool> vb(8, false);
std::vector<char> vc(8, 0);
std::printf("A: %zu %zu\n", sizeof(vb), sizeof(vc));
printFirst(vb);
printFirst(vc);
flipFirst(vb);
flipFirst(vc);
std::printf("B: %d %d\n", static_cast<int>(vb[0]), static_cast<int>(vc[0]));
// 아래 줄들은 왜 문제가 되는가?
// bool& r = vb[0];
// bool* p = &vb[0];
vb[3] = true;
std::printf("C: %d\n", static_cast<int>(vb[3]));
std::vector<bool> big(5000, false);
auto ref = vb[3];
vb = big; // 대입으로 내부 버퍼가 교체될 수 있다
std::printf("D: %d\n", static_cast<int>(ref));
return 0;
} 내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.