[C++]std:vector 특수화

12682 단어 C++잘못거푸집tech

※ 수정/추기 1 (2022년 3월 16일 14:25)


@yaito3014님의 지적
std::vector is a possibly space-efficient specialization of std::vector for the type bool.
'std:vector은 공간 효율이 좋은 특수화일 수 있다[1]'보다는'std:vector은 공간 효율이 좋은 가능성의 특수화'라고 할 수 있다. 학급 템플릿 std:vector가 bool을 특수화하는 것 자체에 의문이 없다.
특수화될 가능성이 있다
이러한 기술에서'std::vector은 클래스 템플릿 std::vector가 특수화되지 않았습니다'는 경우입니다.
글의 제목과 오역 부분을 수정하다.

요약


  • std:vector:operator[]를 사용할 때 error: cannot bind non-const lvalue reference of type 'bool&' to an rvalue of type 'bool'의 컴파일 오류가 발생했습니다.

  • std::vector<bool> - cppreference.com에 따르면 표준 라이브러리에서 메모리 효율을 높이기 위해std::vector<bool>를 특수화할 가능성이 있다.
    std::vector<bool> - cppreference.com에 따라std::vector<bool>는 공간 효율이 좋은 가능성의 특수화를 진행했다.(수정/추기 1)
    그러므로
  • std:vector`가 반드시 배열처럼 연속적으로 저장되는 것은 아니다.
  • std::vector<bool>operator[]는 bool & 가 아닌 소자에 접근하는 클래스를 되돌려줍니다.

  • 상기 컴파일 오류의 원인은 std::vector<bool>::operator[]의 반환 값의 유형이 bool & 이 아니기 때문입니다.
  • 문제 예


    VectorWrapper<T>레벨


    예를 들어 아래std::vector<T>의 포장류 VectorWrapper를 고려한다.
    이 클래스는 다음과 같은 기능을 실현했다. operator[] 를 다시 쓰기를 통해, 진열처럼 index를 지정하여 값을 얻거나 대입할 수 있다.
    #include <iostream>
    #include <vector>
    
    // std::vector<T>のラッパークラス
    template <typename T>
    class VectorWrapper {
        std::vector<T> v;
    }
    
    public:
        VectorWrapper(int size) : v(size) {}
        inline const T& operator[](size_t index) const { 
            return  v[index];
        }
        inline T& operator[](size_t index) {
            return v[index];
        }
    };
    
    에 정의된 VectorWrapper의 유형 T를 int형으로 하고 다음 코드를 컴파일하고 실행합니다.
    int main() {
        VectorWrapper<int> vwInt(10);
        std::cout << "vwInt[2]の値: " << vwInt[2] << std::endl;
        std::cout << "vwInt[2] = 3; を実行" << std::endl;
        vwInt[2] = 3;
        std::cout << "vwInt[2]の値: " << vwInt[2] << std::endl;
    }
    
    의 코드에서 Vector Warrper는 배열과 같은 방식으로 실행하기를 원하지만 출력에는 문제가 없습니다.
    vwInt[2]の値: 0
    vwInt[2] = 3; を実行
    vwInt[2]の値: 3
    

    VectorWrapper≥bool>에서 컴파일 오류


    다음에 T = bool로 같은 코드를 컴파일합니다.
    int main() {
        VectorWrapper<bool> vwBool(10);
        std::cout << "vwBool[2]の値: " << vwInt[2] << std::endl;
        std::cout << "vwBool[2] = 3; を実行" << std::endl;
        vwBool[2] = 3; \\ error!
        std::cout << "vwBool[2]の値: " << vwInt[2] << std::endl;
    }
    
    위의 코드를 컴파일할 때 다음과 같은 오류가 발생합니다.
    error: cannot bind non-const lvalue reference of type 'bool&' to an rvalue of type 'bool'
    15 |         return v[index];
    

    까닭


    참조std:vector 참조, std::vector<T, Allocator>::operator[] 반환reference 유형.referencevalue_type&T&에서 정의되었기 때문에 맨 위에 있는 코드std::vector<int>::operator[]에서 되돌아오기int&.여기까지 예상대로
    그러나 참조std:vector〃bool>의 참조
    std::vector is a possibly space-efficient specialization of std::vector for the type bool.
    따라서 표준 라이브러리에서 메모리 효율을 높일 가능성std::vector<bool>이 특수화될 수 있다.
    표준 라이브러리에서std::vector<bool>는 공간 효율이 좋은 가능성을 특수화했다.(※ 수정/보충1)
    그 밖에
    ・Does not necessarily store its elements as a continguous aray.
    ・Exposes class std:vector<bool>:reference asa method of accessing individual bits.In particular, objects of this class are returned by operator[] by value.
    이런 견해가 있다.즉
  • std::vector<bool> 반드시 정렬처럼 연속적으로 저장되는 것은 아니다.
  • std::vector<bool>operator[]는 bool & 가 아닌 소자에 접근하는 클래스를 되돌려줍니다.
  • 이전c++ - Non const lvalue references - Stack Overflow, 위 코드에서 std::vector<bool>의 반환값의 유형은 bool에 접근하는 클래스operator[]이기 때문에 형식 변환을 거친 임시 대상bool을 생성하지만 C++는 임시 대상에 대한 비const 참고를 허용하지 않기 때문에 오류가 발생할 수 있습니다.

    총결산

  • 표준 라이브러리에서 메모리 효율을 높이기 위해std::vector<bool>를 특수화할 수 있다.
  • std:vector은 공간 효율이 좋은 가능성의 특수화를 진행하였다.(※ 수정/보충1)
  • std:vector`가 반드시 배열처럼 연속적으로 저장되는 것은 아니다.
  • std::vector<bool>operator[]는 bool & 가 아닌 소자에 접근하는 클래스를 되돌려줍니다.
  • 참고 자료

  • std::vector - cppreference.com
  • std::vector<bool> - cppreference.com
  • c++ - Non const lvalue references - Stack Overflow
  • 템플릿 특수화 | Programing Place C++ 편 [언어 해설] 제23장
  • 좋은 웹페이지 즐겨찾기