STL (g) of the extraction C ++ Standard Library (vii) of the traits technology

C ++ Standard Library (vii) of the traits technology

traits technology

Principle: the use of template argument deduction mechanism to get the parameters passed in type.

template<typename T>
struct Iter { typedef T value_type; .... } template<typename T> typename T::value_type func(T* ite) {return *ite;}

This degree, still encounter a problem: If it is not a class type (such as pointers, references), it is not possible to derive the correct parameters. You can use partial template specialization to handle this situation:

template<typename T>
struct Iter<T*> { typename T value_type; };

We need to address the core issue: how to get the iterator type described in the technical traits do?

template<typename T>
struct iterator_traits { typedef typename T::iterator_category iterator_category; typedef typename T::value_type value_type; typedef typename T::difference_type difference_type; typedef typename T::pointer pointer; typedef typename T::reference reference; };

At the same time, iterator_traits must be typed for the incoming pointer and pointer-to-const to design specializations.

template<typename T>
struct iterator_traits<T*> { ... typedef random_access_iterator_tag iterator_category; } template<typename T> struct iterator_traits<const T*> { ... typedef random_access_iretator_tag iterator_category; }

Do not type:

  • type value : Description iterator pointing object type.
  • type -difference : the distance between the two described iterator, using the built-in C ++ type ptrdiff_t default
  • of the type Reference : Description iterator that references to objects
  • type pointer : Description of the pointer to the object iterator
  • iterator_category : Description respective gender iterator
    • Iterator the INPUT : read-only iterator
    • Iterator the Output : write-only iterator
    • Iterator Forward : read-write iterators
    • The Iterator Bidirectional : two-way mobile iterator, can read and write
    • Access the Iterator the Random : iterator random movement, can read and write

The use of overloading, on the choice of different versions of the function of different versions of iterators through at compile time:

template<typename category,typename T,typename dis=ptrdiff_t,typename poin=T*,typename ref=T&> struct iterator { typedef category iterator_category; typedef T value_type; typedef dis difference_type; typedef poin pointer; typedef ref reference; }; struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; template <typename InputIterator,typename Distance> inline void __advance(InputIterator& iter,Distance n,input_iterator_tag) { while(n--) ++iter; } template <typename ForwardIterator,typename Distance> inline void __advance(ForwardIterator& iter,Distance n,forward_iterator_tag) { __advance(i,n,input_iterator_tag()); } template <typename BidirectionalIterator,typename Distance> inline void __advance(BidirectionalIterator& iter,Distance n,bidirectional_iterator_tag) { if(n > 0) while(n--) ++iter; if(n < 0) while(n--) --iter; } template <typename RandomAccessIterator,typename Distance> inline void __advance(RandomAccessIterator& iter,Distance n,random_access_iterator_tag) { iter += n; }

According traits mechanism, the need to use the following wrapper:

template <typename InputIterator,typename Distance>
inline void __advance(InputIterator& iter,Distance n) { __advance(i,n,iteratir_traits<InputIterator>::iterator_category()); }

Sourcing other functions:

template<typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category iteratir_category(const Iterator&) { typedef typename iterator_traits<Iterator>::iterator_category category; return category(); } template<typename Iterator> inline typename iterator_traits<Iterator>::distance_type* distance_type(const Iterator&) { return static_cast<typename iterator_traits<Iterator>::distance_type*>(0); } template<typename T> inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&) { return static_cast<typename iterator_traits<Iterator>::value_type*>(0); } 

to sum up

Proper design types, is the responsibility of iterators.
Design appropriate iterator is the responsibility of the vessel.

__type_traits
traits technology to make up for lack of the C ++ language itself, but traits technology not only exists in Iterator, also present in STL. iterator_traits responsible iterator characteristics extraction, __ type_traits is responsible for the extraction type parameter. Type parameter here refers to: whether this type do not have a non-trivial default ctor? Whether non-trivial copy ctor? Whether non-travial assignment operator? Whether non-trravial dctor? If not, we can use memcpy (), memmove () to take the most effective action. Otherwise, the need for complex operations according ctor, copy, dctor and so on.
You can use the following iterator_traits similar manner:

__type_traits<T>::has_trivial_default_constructor
__type_traits<T>::has_trivial_copy_constructor
__type_traits<T>::has_trivial_assignment_operator
__type_traits<T>::has_trivial_destructor
__type_traits<T>::is_POD_type

struct __true_type {};
struct __false_type {}; template<typename T> struct __type_traits { typedef __false_type has_trivial_default_constructor; typedef __false_type has_trivial_copy_constructor; typedef __false_type has_trivial_assignment_operator typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type; }

STL is the most conservative of all the values ​​embedded in the definition of sex, and then to provide the type of decency (char, long, int, double) and other appropriate design specializations.

__STL_TEMPLATE_NULL struct __type_traits<bool> {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct __type_traits<char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct __type_traits<wchar_t> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct __type_traits<short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct __type_traits<long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_LONG_LONG */ __STL_TEMPLATE_NULL struct __type_traits<float> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class _Tp> struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_TEMPLATE_NULL struct __type_traits<char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; };

traits technology

Principle: the use of template argument deduction mechanism to get the parameters passed in type.

template<typename T>
struct Iter { typedef T value_type; .... } template<typename T> typename T::value_type func(T* ite) {return *ite;}

This degree, still encounter a problem: If it is not a class type (such as pointers, references), it is not possible to derive the correct parameters. You can use partial template specialization to handle this situation:

template<typename T>
struct Iter<T*> { typename T value_type; };

We need to address the core issue: how to get the iterator type described in the technical traits do?

template<typename T>
struct iterator_traits { typedef typename T::iterator_category iterator_category; typedef typename T::value_type value_type; typedef typename T::difference_type difference_type; typedef typename T::pointer pointer; typedef typename T::reference reference; };

At the same time, iterator_traits must be typed for the incoming pointer and pointer-to-const to design specializations.

template<typename T>
struct iterator_traits<T*> { ... typedef random_access_iterator_tag iterator_category; } template<typename T> struct iterator_traits<const T*> { ... typedef random_access_iretator_tag iterator_category; }

Do not type:

  • type value : Description iterator pointing object type.
  • type -difference : the distance between the two described iterator, using the built-in C ++ type ptrdiff_t default
  • of the type Reference : Description iterator that references to objects
  • type pointer : Description of the pointer to the object iterator
  • iterator_category : Description respective gender iterator
    • Iterator the INPUT : read-only iterator
    • Iterator the Output : write-only iterator
    • Iterator Forward : read-write iterators
    • The Iterator Bidirectional : two-way mobile iterator, can read and write
    • Access the Iterator the Random : iterator random movement, can read and write

The use of overloading, on the choice of different versions of the function of different versions of iterators through at compile time:

template<typename category,typename T,typename dis=ptrdiff_t,typename poin=T*,typename ref=T&> struct iterator { typedef category iterator_category; typedef T value_type; typedef dis difference_type; typedef poin pointer; typedef ref reference; }; struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; template <typename InputIterator,typename Distance> inline void __advance(InputIterator& iter,Distance n,input_iterator_tag) { while(n--) ++iter; } template <typename ForwardIterator,typename Distance> inline void __advance(ForwardIterator& iter,Distance n,forward_iterator_tag) { __advance(i,n,input_iterator_tag()); } template <typename BidirectionalIterator,typename Distance> inline void __advance(BidirectionalIterator& iter,Distance n,bidirectional_iterator_tag) { if(n > 0) while(n--) ++iter; if(n < 0) while(n--) --iter; } template <typename RandomAccessIterator,typename Distance> inline void __advance(RandomAccessIterator& iter,Distance n,random_access_iterator_tag) { iter += n; }

According traits mechanism, the need to use the following wrapper:

template <typename InputIterator,typename Distance>
inline void __advance(InputIterator& iter,Distance n) { __advance(i,n,iteratir_traits<InputIterator>::iterator_category()); }

Sourcing other functions:

template<typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category iteratir_category(const Iterator&) { typedef typename iterator_traits<Iterator>::iterator_category category; return category(); } template<typename Iterator> inline typename iterator_traits<Iterator>::distance_type* distance_type(const Iterator&) { return static_cast<typename iterator_traits<Iterator>::distance_type*>(0); } template<typename T> inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&) { return static_cast<typename iterator_traits<Iterator>::value_type*>(0); } 

to sum up

Proper design types, is the responsibility of iterators.
Design appropriate iterator is the responsibility of the vessel.

__type_traits
traits technology to make up for lack of the C ++ language itself, but traits technology not only exists in Iterator, also present in STL. iterator_traits responsible iterator characteristics extraction, __ type_traits is responsible for the extraction type parameter. Type parameter here refers to: whether this type do not have a non-trivial default ctor? Whether non-trivial copy ctor? Whether non-travial assignment operator? Whether non-trravial dctor? If not, we can use memcpy (), memmove () to take the most effective action. Otherwise, the need for complex operations according ctor, copy, dctor and so on.
You can use the following iterator_traits similar manner:

__type_traits<T>::has_trivial_default_constructor
__type_traits<T>::has_trivial_copy_constructor
__type_traits<T>::has_trivial_assignment_operator
__type_traits<T>::has_trivial_destructor
__type_traits<T>::is_POD_type

struct __true_type {};
struct __false_type {}; template<typename T> struct __type_traits { typedef __false_type has_trivial_default_constructor; typedef __false_type has_trivial_copy_constructor; typedef __false_type has_trivial_assignment_operator typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type; }

STL is the most conservative of all the values ​​embedded in the definition of sex, and then to provide the type of decency (char, long, int, double) and other appropriate design specializations.

__STL_TEMPLATE_NULL struct __type_traits<bool> {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct __type_traits<char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct __type_traits<wchar_t> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct __type_traits<short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct __type_traits<long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_LONG_LONG */ __STL_TEMPLATE_NULL struct __type_traits<float> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class _Tp> struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_TEMPLATE_NULL struct __type_traits<char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; };

Guess you like

Origin www.cnblogs.com/xcb-1024day/p/11332501.html