[c++] libc ++의 vector <bool> :: const_reference가 bool이 아닌 이유는 무엇입니까?

섹션 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_referencevector<T>::referencevector<T>::const_referencevector

libc ++에서 위의 내용 testvector<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_typevectorarray.

libc ++의 확장으로 시작된 C ++ 11 및 C ++ 14 기능의 여러 예가 있습니다. 이것이 표준이 진화하는 방식입니다. 실제로 입증 된 긍정적 인 현장 경험은 강력한 영향을 미칩니다. 표준 담당자는 기존 사양을 변경할 때 보수적입니다. 정확하게 추측하고 있다고 확신하는 경우에도 추측은 국제적으로 인정받는 표준을 발전시키기위한 위험한 전략입니다.


답변