짝퉁 STL 구현의traits, construct &destruct

10010 단어 struct
traits 기술은 STL에 광범위하게 응용되고 있으며, 이를 통해 대상의 특성을 쉽게 추출할 수 있습니다.STL에서도 이를 통해 성능을 최적화시킨다. 예를 들어 하나의 대상이 POD 대상(Plain Old Data)이면 복사 과정에서memcpy 등 함수를 직접 복사할 수 있고 복사 구조 함수나operator=를 호출할 필요가 없다.먼저 STL에서 가장 기본적인 대상인iterator를 보도록 하겠습니다.
        template <typename T, typename Size = size_t, typename Difference = ptrdiff_t>
        struct iterator
        {
            typedef T                               value_type;
            typedef Difference                      difference_type;
            typedef T*                              pointer;
            typedef T&                              reference;
            typedef const T*                        const_pointer;
            typedef const T&                        const_reference;
            typedef iterator<T, Size, Difference>   self;
        };

        template <typename T, typename Size = size_t, typename Difference = ptrdiff_t>
        struct const_iterator : public iterator<T>
        {
        };

상기 코드에서 알 수 있듯이 모든iterator에 대해value 를 정의해야 합니다type,size_type,difference_type,pointer,reference,const_pointer,const_reference와self 형식입니다.1. valuetypevalue_type은 이 교체기가 저장한 값 유형을 표시합니다. 2,differencetypedifference_type은 두 교체기 사이의 거리 유형을 표시하는 데 사용됩니다. 3,pointer,reference,constpointer,const_reference는 각각 가리키는 물건의 지침, 인용, 지침 상량과 인용 상량의 유형이다. 넷째,selfself는 이 교체기 자체의 유형이다. 다음에iteratortraits,iterator_traits는 주로 교체기iterator의 값 유형 등을 추출하는 데 쓰인다
        template <typename Iterator>
        struct iterator_traits
        {
            typedef typename Iterator::value_type      value_type;
            typedef typename Iterator::difference_type difference_type;
            typedef typename Iterator::pointer         pointer;
            typedef typename Iterator::reference       reference;
            typedef typename Iterator::const_pointer   const_pointer;
            typedef typename Iterator::const_reference const_reference;
            typedef typename Iterator::self            self_type;
        };

여기서 한 가지 미리 예고할 수 있는 것은vector는 용기로서 그 내부는 지침을 교체기로 사용한다. 그러면 우리는 어떻게 그것의 값 유형을 추출합니까?답은 간단하고 특례화되면 우리는iteratortraits는 각각 두 가지 T*와constT*의 특례화를 한다
        template <typename T>
        struct iterator_traits<T*>
        {
            typedef T         value_type;
            typedef ptrdiff_t difference_type;
            typedef T*        pointer;
            typedef T&        reference;
            typedef const T*  const_pointer;
            typedef const T&  const_reference;
            typedef T*        self_type;
        };

        template <typename T>
        struct iterator_traits<const T*>
        {
            typedef T         value_type;
            typedef ptrdiff_t difference_type;
            typedef T*        pointer;
            typedef T&        reference;
            typedef const T*  const_pointer;
            typedef const T&  const_reference;
            typedef const T*  self_type;
        };

이로써 우리는iteratortraits에서 모든iterator의 값 유형 등을 추출했습니다.앞서 말했듯이traits를 통해 일부 대상의 특성을 추출하여 코드의 효율을 높일 수 있다.사실은 그렇다. 트레이스를 통해 하나의 대상이 POD 대상인지 추출할 수 있다. POD 대상에 대해 우리가 복사할 때, 그 복사 구조 함수나operator=를 사용해서는 안 되고,memcpy를 사용하면 효율이 더욱 높다.다음은type_traits
        struct __true_type
        {
        };

        struct __false_type
        {
        };

        template <typename T>
        struct __type_traits
        {
            typedef __true_type  has_default_construct;
            typedef __true_type  has_copy_construct;
            typedef __true_type  has_assign_operator;
            typedef __true_type  has_destruct;
            typedef __false_type is_POD;
        };

빼놓을 수 없는 것은 그중에서 각각 을 사용한다는 것이다true_type 및false_type은 이 특성이 존재하는지 여부를 표시합니다.그러면 우리는 어떻게 기초 유형인 int,char 등의 특성을 추출합니까?답은 여전히 특례화되어 있으며, 이 코드는 더 이상 붙이지 않으며, 문말에는 전체 코드의 상세한 주소를 제시할 것이다.마지막으로 우리 하나hashDestruct의 함수로 이 형식에 분석 함수가 있는지 추출합니다.
        template <typename T>
        inline auto has_destruct(const T&)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
        {
            return static_cast<typename __type_traits<T>::has_destruct*>(0);
        }

        template <typename T>
        inline auto has_destruct(T*)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
        {
            static_assert(false, "Please use const T& not T*");
            return static_cast<typename __type_traits<T>::has_destruct*>(0);
        }

        template <typename T>
        inline auto has_destruct(const T*)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
        {
            static_assert(false, "Please use const T& not const T*");
            return static_cast<typename __type_traits<T>::has_destruct*>(0);
        }

어쩔 수 없이 C++0x는 정말 강력합니다. 형삼을 통해 되돌아오는 값의 유형을 확인할 수 있습니다. 그러면 우리는 이 유형의has 를 추출할 수 있습니다.destruct 도메인은 입니다.true_type 또는false_type이야.마지막으로 construct와destruct의 코드를 보십시오. STL에서 대상의 메모리 분배와 구조는 분리되어 있으며, 기초 대상인 int,char 등은 분석할 때 분석 함수를 호출할 필요가 없습니다.다음은 construct와destruct의 실현을 보겠습니다.
        template <typename T1, typename T2>
        inline void construct(T1* p, const T2& value)
        {
            new (p) T1(value);
        }

        template <typename T>
        inline void destruct(T* p, __true_type*)
        {
            p->~T();
        }

        template <typename T>
        inline void destruct(T*, __false_type*)
        {
        }

        template <typename ForwardIterator>
        inline void destruct(ForwardIterator first, ForwardIterator last)
        {
            while(first != last)
            {
                destruct(&*first, has_destruct(*first));
                ++first;
            }
        }

이로써traits기술과construct 및destruct에 대한 설명이 완료되었으니 완전한 코드는http://qlanguage.codeplex.com/에서 다운로드하십시오

좋은 웹페이지 즐겨찾기