1、源码

template<class _UnaryFuncT, class _SourceIteratorT, class _SourceValueT, class _ValueT>
class transform_iterator :
public __composition_iterator<transform_iterator<_UnaryFuncT, _SourceIteratorT, _SourceValueT, _ValueT>,
_SourceIteratorT, _SourceValueT> {
public:
using __parent_t = __composition_iterator<transform_iterator<_UnaryFuncT, _SourceIteratorT, _SourceValueT, _ValueT>,
_SourceIteratorT, _SourceValueT>;
typedef convert_pointer_t<_SourceIteratorT, _ValueT> __pointer_t;
typedef std::iterator_traits<__pointer_t> __std_iterator_traits;
_UnaryFuncT func;
typedef typename _SourceIteratorT::iterator_category iterator_category;
typedef typename _SourceIteratorT::difference_type difference_type;
typedef typename __std_iterator_traits::value_type value_type;
typedef typename __std_iterator_traits::pointer pointer;
typedef typename __std_iterator_traits::reference reference;
transform_iterator() : __parent_t() {};
transform_iterator(_SourceIteratorT const& it, _UnaryFuncT f) : func(f), __parent_t(it) {}
explicit transform_iterator(_SourceIteratorT const& it) : __parent_t(it) {};
transform_iterator(const transform_iterator& other) : __parent_t(other.source_it), func(other.func) {}
transform_iterator& operator=(const transform_iterator& other) {
this->source_it = other.source_it;
this->func = other.func;
return *this;
}
transform_iterator(transform_iterator&& other) : __parent_t(other.source_it), func(other.func) {
this->source_it = other.source_it;
}
transform_iterator& operator=(transform_iterator&& other) {
this->source_it = other.source_it;
this->func = other.func;
return *this;
}
inline reference operator*() const { return func(*this->source_it); }
inline pointer operator->() const { return &func(*this->source_it); }
template<typename ReferenceT = reference>
inline std::enable_if_t<std::is_same_v<ReferenceT, reference>&&
std::is_same_v<iterator_category, std::random_access_iterator_tag>, ReferenceT>
operator[](difference_type __n) const {
static_assert(std::is_same_v<iterator_category, std::random_access_iterator_tag>);
return func(this->source_it[__n]);
}
inline const pointer base() const { return &func(*(this->source_it)); }
};
/*!
* @brief   Convenient method to make a transform_iterator with template deduction, for a given Conversion
*/
template<typename _ConversionT, typename _SourceIteratorT>
slam::transform_iterator<_ConversionT,
_SourceIteratorT,
typename _SourceIteratorT::value_type,
typename _ConversionT::value_type> make_transform(_SourceIteratorT it,
_ConversionT) {
static_assert(std::is_same_v<typename _ConversionT::conversion_category, reference_conversion_tag>,
"A transform iterator can only be applied with a conversion mapping two references");
return slam::transform_iterator<_ConversionT, _SourceIteratorT,
typename _SourceIteratorT::value_type, typename _ConversionT::value_type>(it);
};
/**
* @brief Returns the pair <begin, end> transform iterators of a collection, for a given Conversion
*/
template<typename _ConversionT, typename _SourceCollection>
std::pair<slam::transform_iterator<_ConversionT,
typename _SourceCollection::iterator,
typename _SourceCollection::iterator::value_type,
typename _ConversionT::value_type>,
slam::transform_iterator<_ConversionT,
typename _SourceCollection::iterator,
typename _SourceCollection::iterator::value_type,
typename _ConversionT::value_type>> make_transform_collection(_SourceCollection& collection,
_ConversionT) {
static_assert(std::is_same_v<typename _ConversionT::conversion_category, reference_conversion_tag>,
"A transform iterator can only be applied with a conversion mapping two references");
return {
make_transform(collection.begin(), _ConversionT()),
make_transform(collection.end(), _ConversionT())
};
}
/**
* @brief Returns the pair <begin, end> transform iterators of a collection, for a given Conversion
*/
template<typename _ConversionT, typename _SourceCollection>
std::pair<slam::transform_iterator<_ConversionT,
typename _SourceCollection::const_iterator,
typename _SourceCollection::const_iterator::value_type,
typename _ConversionT::value_type>,
slam::transform_iterator<_ConversionT,
typename _SourceCollection::const_iterator,
typename _SourceCollection::const_iterator::value_type,
typename _ConversionT::value_type>> make_transform_collection(const _SourceCollection& collection,
_ConversionT) {
static_assert(std::is_same_v<typename _ConversionT::conversion_category, reference_conversion_tag>,
"A transform iterator can only be applied with a conversion mapping two references");
return {
make_transform(collection.begin(), _ConversionT()),
make_transform(collection.end(), _ConversionT())
};
}

2、代码解析

代码解析:transform_iterator

该代码定义了一个**transform_iterator变换迭代器)**,它将一个迭代器的值通过UnaryFunction(一元函数)转换为不同类型的值,从而提供了一种在迭代时进行值转换的方式。

1.transform_iterator类解析

该类继承自__composition_iterator,是一个泛型迭代器,它的核心功能是:

  • 存储一个基础迭代器(_SourceIteratorT)
  • 存储一个转换函数(_UnaryFuncT)
  • 在operator*()及operator->()中,应用转换函数

1.1transform_iterator的主要成员

template<class _UnaryFuncT, class _SourceIteratorT, class _SourceValueT, class _ValueT>
class transform_iterator :
public __composition_iterator<transform_iterator<_UnaryFuncT, _SourceIteratorT, _SourceValueT, _ValueT>,
_SourceIteratorT, _SourceValueT> {
  • _UnaryFuncT:一个一元函数(如 lambda、仿函数或函数指针),用于转换值。
  • _SourceIteratorT:源迭代器类型(如std::vector<int>::iterator)。
  • _SourceValueT:源迭代器的值类型。
  • _ValueT:转换后值的类型。

1.2 主要类型定义

using __parent_t = __composition_iterator<transform_iterator<_UnaryFuncT, _SourceIteratorT, _SourceValueT, _ValueT>,
_SourceIteratorT, _SourceValueT>;
typedef convert_pointer_t<_SourceIteratorT, _ValueT> __pointer_t;
typedef std::iterator_traits<__pointer_t> __std_iterator_traits;
  • __parent_t:继承自__composition_iterator,封装了基本的迭代器功能。
  • __pointer_t:用于获取指向_ValueT的指针类型。
  • __std_iterator_traits:用于提取标准迭代器的value_typepointerreference等类型。

1.3 迭代器所需的类型

typedef typename _SourceIteratorT::iterator_category iterator_category;
typedef typename _SourceIteratorT::difference_type difference_type;
typedef typename __std_iterator_traits::value_type value_type;
typedef typename __std_iterator_traits::pointer pointer;
typedef typename __std_iterator_traits::reference reference;

这些类型是标准迭代器需要提供的基本类型。

2.transform_iterator的构造函数

transform_iterator() : __parent_t() {};
  • 默认构造函数,创建空的transform_iterator
transform_iterator(_SourceIteratorT const& it, _UnaryFuncT f) : func(f), __parent_t(it) {}
  • 通过it(源迭代器)和f(转换函数)初始化。
explicit transform_iterator(_SourceIteratorT const& it) : __parent_t(it) {};
  • 仅使用源迭代器初始化,转换函数未提供。
transform_iterator(const transform_iterator& other) : __parent_t(other.source_it), func(other.func) {}
  • 复制构造函数。
transform_iterator(transform_iterator&& other) : __parent_t(other.source_it), func(other.func) {
this->source_it = other.source_it;
}
  • 移动构造函数。

3. 重载运算符

3.1operator*(解引用运算符)

inline reference operator*() const { return func(*this->source_it); }
  • 通过funcsource_it指向的值进行转换,并返回结果。

3.2operator->(指针访问运算符)

inline pointer operator->() const { return &func(*this->source_it); }
  • 计算转换后的值,并返回指针。

3.3operator[](随机访问)

template<typename ReferenceT = reference>
inline std::enable_if_t<std::is_same_v<ReferenceT, reference> &&
std::is_same_v<iterator_category, std::random_access_iterator_tag>, ReferenceT>
operator[](difference_type __n) const {
static_assert(std::is_same_v<iterator_category, std::random_access_iterator_tag>);
return func(this->source_it[__n]);
}
  • 仅当迭代器支持随机访问(random access)时,允许使用operator[]

4.make_transform函数

该函数用于创建transform_iterator对象,并根据_ConversionT自动推导类型。

template<typename _ConversionT, typename _SourceIteratorT>
slam::transform_iterator<_ConversionT, _SourceIteratorT,
typename _SourceIteratorT::value_type, typename _ConversionT::value_type>
make_transform(_SourceIteratorT it, _ConversionT) {
static_assert(std::is_same_v<typename _ConversionT::conversion_category, reference_conversion_tag>,
"A transform iterator can only be applied with a conversion mapping two references");
return slam::transform_iterator<_ConversionT, _SourceIteratorT,
typename _SourceIteratorT::value_type, typename _ConversionT::value_type>(it);
}
  • _ConversionT:转换逻辑,必须是引用转换(reference_conversion_tag)。
  • _SourceIteratorT:源容器的迭代器类型。
  • typename _SourceIteratorT::value_type:源数据类型。
  • typename _ConversionT::value_type:转换后数据类型。

5.make_transform_collection

该函数用于创建transform_iterator迭代整个集合。

5.1 非常规版本

template&lt;typename _ConversionT, typename _SourceCollection&gt;
std::pair&lt;slam::transform_iterator&lt;_ConversionT,
typename _SourceCollection::iterator,
typename _SourceCollection::iterator::value_type,
typename _ConversionT::value_type&gt;,
slam::transform_iterator&lt;_ConversionT,
typename _SourceCollection::iterator,
typename _SourceCollection::iterator::value_type,
typename _ConversionT::value_type&gt;&gt;
make_transform_collection(_SourceCollection&amp; collection, _ConversionT) {
static_assert(std::is_same_v&lt;typename _ConversionT::conversion_category, reference_conversion_tag&gt;,
"A transform iterator can only be applied with a conversion mapping two references");
return {
make_transform(collection.begin(), _ConversionT()),
make_transform(collection.end(), _ConversionT())
};
}
  • 创建begin 和 end 的 transform_iterator。

5.2const版本

template&lt;typename _ConversionT, typename _SourceCollection&gt;
std::pair&lt;slam::transform_iterator&lt;_ConversionT,
typename _SourceCollection::const_iterator,
typename _SourceCollection::const_iterator::value_type,
typename _ConversionT::value_type&gt;,
slam::transform_iterator&lt;_ConversionT,
typename _SourceCollection::const_iterator,
typename _SourceCollection::const_iterator::value_type,
typename _ConversionT::value_type&gt;&gt;
make_transform_collection(const _SourceCollection&amp; collection, _ConversionT) {
return {
make_transform(collection.begin(), _ConversionT()),
make_transform(collection.end(), _ConversionT())
};
}
  • 适用于const容器。

总结

  • transform_iterator包装原始迭代器,并在访问时应用转换函数_UnaryFuncT
  • operator*()operator->()应用转换逻辑。
  • make_transform创建transform_iterator
  • make_transform_collection创建整个集合的transform_iteratorbegin()end())。

这种模式适用于懒加载转换,避免显式创建新数据结构,提高效率。

到此这篇关于C++变换迭代器使用方法小结的文章就介绍到这了,更多相关C++变换迭代器使用内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

声明:本站(华域联盟www.cnhackhy.com)所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。