2017-09-08 6 views
11

std::vector<bool>의 특수화는 C++ 11 23.3.7/1에 지정된대로 데이터 멤버를 선언하지 않습니다 (예 : herehere).std :: vector <bool>에 .data()가없는 이유는 무엇입니까?

질문 : 왜 std :: vector에는 .data()가 없습니까? 이것은 왜 bool의 벡터가 연속적으로 메모리에 저장되지 않는 것과 동일한 질문입니다. 그렇게하지 않으면 어떤 이점이 있습니까?

왜 bool 배열에 대한 포인터가 반환되지 않습니까?

+2

'벡터 '는 bool을 여러 바이트로 묶어 공간을 최적화 할 수 있습니다. 'data()'는 그 이익을 제거합니다. – Jarod42

+3

이점은 8 배 적은 메모리를 사용한다는 것입니다. 단점은 사람들의 기대를 망쳐 버리는 것입니다. 이점보다 더 중요한 단점이 있다고 결론지었습니다. – nwp

+3

'std :: vector '은 어머니가 법에 따라 당신과 함께 살도록 초대하는 것과 같습니다.그 때 좋은 생각처럼 보일지 모르지만 결국 전체 아이디어를 후회하게됩니다. 다행히 나는이 허물 중 하나에 대해서만 신용 할 수 있습니다. – Bathsheba

답변

23

왜 std :: vector에는 .data()가 없습니까?

std::vector<bool>은 1 바이트에 여러 값을 저장하기 때문에.

모든 부울 값이 1 비트를 필요로하는 압축 저장 시스템처럼 생각하십시오. 대신 메모리 블록 당 하나 개의 요소 (배열 셀 당 하나 개의 요소) 필요없이 그래서, 메모리 레이아웃은 다음과 같이 보일 수 있습니다 :

enter image description here

을 값을 얻기 위해 인덱스에 당신이 원하는 블록을 가정하면, 어떻게 것 당신은 연산자 []을 사용합니까? bools을 저장하는 bool&을 반환 할 수 없으므로 bool*을 할당 할 수 없습니다. 즉 bool *bool_ptr =&v[0];이 아니고 유효한 코드이므로 컴파일 오류가 발생합니다.

또한 올바른 구현에는 해당 특수화가 없을 수 있으며 메모리 최적화 (압축)를 수행하지 않을 수 있습니다. 따라서 data()은 구현에 따라 예상되는 리턴 유형으로 복사해야합니다 (또는 표준은이를 허용하는 대신 최적화해야합니다).

왜 bool 배열에 대한 포인터가 반환되지 않습니까? std::vector<bool>가 bools 배열로 저장되지 때문에

, 따라서 아무런 포인터는 간단한 방식으로 반환 될 수있다. 배열에 데이터를 복사하고 그 배열을 반환함으로써 그렇게 할 수 있습니다. 그러나 그렇게하지 않는 것이 디자인 선택입니다 (만약 그렇다면 모든 컨테이너에 대해 data()으로 작동한다고 생각합니다).

이렇게하지 않으면 어떤 이점이 있습니까?

메모리 최적화.

일반적으로 단일 바이트에 여러 비트를 저장하므로 메모리 사용량이 8 배 줄어 듭니다. 정확히 말하자면, CHAR_BIT 번 적습니다.

+1

BTW, 올바른 구현은 해당 전문화되지 않았을 수도 있고 메모리 최적화를 수행하지 않을 수도 있습니다. 따라서'data()'는 구현에 따라 예상되는 반환 유형으로 복사해야합니다. (또는 표준은 그것을 허용하는 대신에 최적화를 강제해야한다). – Jarod42

+2

"8 배 이하"는 * 필연적 * 사실이 아니며 그렇지 않은 경우 canonity에 대한 찬성을 갖는이 대답을 망칠 수 있습니다. 'CHAR_BIT' 또는 이와 유사한 것으로 수정합니까? – Bathsheba

+1

@gsamaras : 만약 내가 할 수 있으면 다시 upvote 줄. – Bathsheba