stl源码剖析 第三章iterator 和 type traits及POD类型

来源:互联网 发布:超级优化txt全集下载 编辑:程序博客网 时间:2024/06/05 08:38

traits就是编译器的类型判断。书上形象的说它是一个“萃取器”,来得到模版参数的特性。

假设现在对外有一个接口,用函数模版实现,要根据传进来的模版参数类型来执行不同的东西,或者返回不同的返回值类型,这个就是traits要解决的问题。

例如:iterator根据移动特性和操作被分为五种:

1 input iterator

2 output iterator

3 forward iterator

4 bidirectional iterator

5 random access iterator

http://blog.csdn.net/study_more/article/details/7799297

他们的关系

现在要实现distance()这个函数,计算两个迭代器之间的距离。

对random access iterator来说,可以直接相减计算。但对于input iterator来说,只能一步步递增第一个迭代器,判断是否等于第二个迭代器,这样来计算。

所以就需要根据不同的迭代器类型来执行不同的操作。 

在iterator_traits这个类模版里边,typedef了不同的迭代器类型,甚至还偏特化了原生指针和pointer_to_const这两个版本。

我们在distance()函数里边调用真正实现的函数_distance(),_distance()比distance()多接受了一个迭代器类型的参数,由category()的返回值iterator_traits<inputiterator>::iterator_category提供,它是一个暂时对象。

template<class inputiterator>inline iterator_traits<inputiterator>::difference_typedistance(inputiterator first, inputiterator last){typedef typename iterator_traits<inputiterator>::iterator_category category;return _distance(first, last, category());} template<class i>inline typename iterator_traits<i>::iterator_categoryiterator_category(const &i){typedef typename iterator_traits<i>::iterator_category category;return category();} 

下边是stl_iterator_base_types.h的内容。注意五个_iterator_tag的继承关系, iterator,iterator_traits,原生指针和指向常量的指针的偏特化版本。

traits技术在迭代器应用之外,还有一种_type_traits负责“萃取”类型的特性。应用在uninitialized_fill_n ,destroy,copy等函数里。 例如当copy的对象是一种trivial(翻译为无意义)类型(基本的内置类型如int等和c结构体类型等)时,可以直接采用内存操作如memmove()、memcpy()等提高性能。 当copy的对象是一种non—trivial类型时,就不得不一个个调用construct()函数。 可以看这篇文章http://blog.csdn.net/a627088424/article/details/48595525

// Copyright (C) 2001-2013 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library.  This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 3, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// Under Section 7 of GPL version 3, you are granted additional// permissions described in the GCC Runtime Library Exception, version// 3.1, as published by the Free Software Foundation.// You should have received a copy of the GNU General Public License and// a copy of the GCC Runtime Library Exception along with this program;// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see// <http://www.gnu.org/licenses/>./* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Silicon Graphics makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. *//** @file bits/stl_iterator_base_types.h *  This is an internal header file, included by other library headers. *  Do not attempt to use it directly. @headername{iterator} * *  This file contains all of the general iterator-related utility types, *  such as iterator_traits and struct iterator. */#ifndef _STL_ITERATOR_BASE_TYPES_H#define _STL_ITERATOR_BASE_TYPES_H 1#pragma GCC system_header#include <bits/c++config.h>#if __cplusplus >= 201103L# include <type_traits>  // For _GLIBCXX_HAS_NESTED_TYPE, is_convertible#endifnamespace std _GLIBCXX_VISIBILITY(default){_GLIBCXX_BEGIN_NAMESPACE_VERSION  /**   *  @defgroup iterators Iterators   *  Abstractions for uniform iterating through various underlying types.  */  //@{   /**   *  @defgroup iterator_tags Iterator Tags   *  These are empty types, used to distinguish different iterators.  The   *  distinction is not made by what they contain, but simply by what they   *  are.  Different underlying algorithms can then be used based on the   *  different operations supported by different iterator types.  */  //@{   ///  Marking input iterators.  struct input_iterator_tag { };  ///  Marking output iterators.  struct output_iterator_tag { };  /// Forward iterators support a superset of input iterator operations.  struct forward_iterator_tag : public input_iterator_tag { };  /// Bidirectional iterators support a superset of forward iterator  /// operations.  struct bidirectional_iterator_tag : public forward_iterator_tag { };  /// Random-access iterators support a superset of bidirectional  /// iterator operations.  struct random_access_iterator_tag : public bidirectional_iterator_tag { };  //@}  /**   *  @brief  Common %iterator class.   *   *  This class does nothing but define nested typedefs.  %Iterator classes   *  can inherit from this class to save some work.  The typedefs are then   *  used in specializations and overloading.   *   *  In particular, there are no default implementations of requirements   *  such as @c operator++ and the like.  (How could there be?)  */  template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,           typename _Pointer = _Tp*, typename _Reference = _Tp&>    struct iterator    {      /// One of the @link iterator_tags tag types@endlink.      typedef _Category  iterator_category;      /// The type "pointed to" by the iterator.      typedef _Tp        value_type;      /// Distance between iterators is represented as this type.      typedef _Distance  difference_type;      /// This type represents a pointer-to-value_type.      typedef _Pointer   pointer;      /// This type represents a reference-to-value_type.      typedef _Reference reference;    };  /**   *  @brief  Traits class for iterators.   *   *  This class does nothing but define nested typedefs.  The general   *  version simply @a forwards the nested typedefs from the Iterator   *  argument.  Specialized versions for pointers and pointers-to-const   *  provide tighter, more correct semantics.  */#if __cplusplus >= 201103L_GLIBCXX_HAS_NESTED_TYPE(iterator_category)  template<typename _Iterator,   bool = __has_iterator_category<_Iterator>::value>    struct __iterator_traits { };  template<typename _Iterator>    struct __iterator_traits<_Iterator, true>    {      typedef typename _Iterator::iterator_category iterator_category;      typedef typename _Iterator::value_type        value_type;      typedef typename _Iterator::difference_type   difference_type;      typedef typename _Iterator::pointer           pointer;      typedef typename _Iterator::reference         reference;    };  template<typename _Iterator>    struct iterator_traits    : public __iterator_traits<_Iterator> { };#else  template<typename _Iterator>    struct iterator_traits    {      typedef typename _Iterator::iterator_category iterator_category;      typedef typename _Iterator::value_type        value_type;      typedef typename _Iterator::difference_type   difference_type;      typedef typename _Iterator::pointer           pointer;      typedef typename _Iterator::reference         reference;    };#endif  /// Partial specialization for pointer types.  template<typename _Tp>    struct iterator_traits<_Tp*>    {      typedef random_access_iterator_tag iterator_category;      typedef _Tp                         value_type;      typedef ptrdiff_t                   difference_type;      typedef _Tp*                        pointer;      typedef _Tp&                        reference;    };  /// Partial specialization for const pointer types.  template<typename _Tp>    struct iterator_traits<const _Tp*>    {      typedef random_access_iterator_tag iterator_category;      typedef _Tp                         value_type;      typedef ptrdiff_t                   difference_type;      typedef const _Tp*                  pointer;      typedef const _Tp&                  reference;    };  /**   *  This function is not a part of the C++ standard but is syntactic   *  sugar for internal library use only.  */  template<typename _Iter>    inline typename iterator_traits<_Iter>::iterator_category    __iterator_category(const _Iter&)    { return typename iterator_traits<_Iter>::iterator_category(); }  //@}  // If _Iterator has a base returns it otherwise _Iterator is returned  // untouched  template<typename _Iterator, bool _HasBase>    struct _Iter_base    {      typedef _Iterator iterator_type;      static iterator_type _S_base(_Iterator __it)      { return __it; }    };  template<typename _Iterator>    struct _Iter_base<_Iterator, true>    {      typedef typename _Iterator::iterator_type iterator_type;      static iterator_type _S_base(_Iterator __it)      { return __it.base(); }    };#if __cplusplus >= 201103L  template<typename _InIter>    using _RequireInputIter = typename      enable_if<is_convertible<typenameiterator_traits<_InIter>::iterator_category,       input_iterator_tag>::value>::type;#endif_GLIBCXX_END_NAMESPACE_VERSION} // namespace#endif /* _STL_ITERATOR_BASE_TYPES_H */
 
原创粉丝点击