섹션 23.3.7 클래스 vector<bool>
[vector.bool], 단락 1은 다음과 같이 설명합니다.
template <class Allocator> class vector<bool, Allocator> {
public:
// types:
typedef bool const_reference;
...
그러나이 프로그램은 libc ++를 사용할 때 컴파일되지 않습니다.
#include <vector>
#include <type_traits>
int
main()
{
static_assert(std::is_same<std::vector<bool>::const_reference, bool>{}, "?");
}
또한 C ++ 표준은이 사양에서 C ++ 98로 거슬러 올라갈 때까지 일관성이있었습니다. 그리고 libc ++는 libc ++가 처음 도입 된 이후로이 사양을 지속적으로 따르지 않았습니다.
이 부적합의 동기는 무엇입니까?
답변
이 확장에 대한 동기는 준수 프로그램에 의해 감지되어 부적합 하며 참조 (const 및 기타)와 관련하여 vector<bool>
더 유사 하게 동작 하도록 만드는 것 vector<char>
입니다.
소개
1998 년부터 vector<bool>
“그렇지 않은 용기”로 조롱되었습니다. 최초의 LWG 문제 중 하나 인 LWG 96 이 토론을 시작했습니다. 17 년이 지난 오늘날에는 vector<bool>
거의 변함이 없습니다.
이 백서 에서는의 동작이의 vector<bool>
다른 모든 인스턴스화와 어떻게 다른지 에 대한 몇 가지 특정 예제를 살펴보고 vector
일반 코드를 손상시킵니다. 그러나 동일한 문서는 vector<bool>
제대로 구현 된 경우 매우 좋은 성능 속성 이 가질 수있는 길이에 대해 설명 합니다.
요약 : vector<bool>
나쁜 컨테이너가 아닙니다. 실제로 매우 유용합니다. 이름이 좋지 않습니다.
돌아가다 const_reference
위에서 소개하고 여기 에 자세히 설명 했듯이 나쁜 점 vector<bool>
은 일반 코드에서 다른 vector
인스턴스화 와 다르게 동작한다는 것 입니다. 다음은 구체적인 예입니다.
#include <cassert>
#include <vector>
template <class T>
void
test(std::vector<T>& v)
{
using const_ref = typename std::vector<T>::const_reference;
const std::vector<T>& cv = v;
const_ref cr = cv[0];
assert(cr == cv[0]);
v[0] = 1;
assert(true == cv[0]);
assert(cr == cv[0]); // Fires!
}
int
main()
{
std::vector<char> vc(1);
test(vc);
std::vector<bool> vb(1);
test(vb);
}
표준 규격은 어설 표시된 것을 말한다 // Fires!
트리거하지만 경우에만 test
으로 실행됩니다 vector<bool>
. 로모그래퍼 실행하면 vector<char>
(또는 vector
외에 bool
적절한 기본이 아닌이 때 T
할당), 시험은 통과한다.
libc ++ 구현은 vector<bool>
제네릭 코드에서 다르게 동작 할 때의 부정적인 영향을 최소화하려고했습니다 . 한 가지는 이것이 확인하는 것입니다 달성했다 프록시 참조를 지정된처럼, 당신은 그것을 통해 할당 할 수 없습니다 것을 제외하고. 즉, libc ++에서 기본적 으로 해당 비트의 복사본이 아니라 내부의 비트에 대한 포인터 입니다.vector<T>::const_reference
vector<T>::reference
vector<T>::const_reference
vector
libc ++에서 위의 내용 test
은 vector<char>
및 vector<bool>
.
비용은 얼마입니까?
단점은 질문에 표시된 것처럼이 확장이 감지 될 수 있다는 것입니다. 그러나 실제로이 별칭의 정확한 유형에 관심이있는 프로그램은 거의 없으며 동작에 관심이있는 프로그램이 더 많습니다.
이 부적합의 동기는 무엇입니까?
libc ++ 클라이언트에게 일반 코드에서 더 나은 동작을 제공하고 아마도 충분한 현장 테스트 후에 전체 C ++ 산업의 향상을 위해 향후 C ++ 표준에 대한이 확장을 제안하십시오.
이러한 제안은 bit_vector
현재와 거의 동일한 API를 vector<bool>
갖지만 const_reference
여기 에서 논의 된 것과 같은 몇 가지 업그레이드 가 포함 된 새 컨테이너 (예 :)의 형태로 제공 될 수 있습니다. vector<bool>
전문화 의 지원 중단 (및 최종 제거)이 이어집니다 . bitset
또한이 부서에서 약간의 업그레이드 (예 : add const_reference
및 반복기 집합)를 사용할 수도 있습니다 .
돌이켜 보면이에 즉, bitset
이다 vector<bool>
(어떤이로 변경해야한다 bit_vector
등, – 또는 무엇이든) array
이다 vector
. 그리고 비유는 우리가 얘기 여부를 성립한다고 bool
는 AS value_type
의 vector
과 array
.
libc ++의 확장으로 시작된 C ++ 11 및 C ++ 14 기능의 여러 예가 있습니다. 이것이 표준이 진화하는 방식입니다. 실제로 입증 된 긍정적 인 현장 경험은 강력한 영향을 미칩니다. 표준 담당자는 기존 사양을 변경할 때 보수적입니다. 정확하게 추측하고 있다고 확신하는 경우에도 추측은 국제적으로 인정받는 표준을 발전시키기위한 위험한 전략입니다.