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.1 transform_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_type、pointer、reference等类型。
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.1 operator*(解引用运算符)
inline reference operator*() const { return func(*this->source_it); }
- 通过
func对source_it指向的值进行转换,并返回结果。
3.2 operator->(指针访问运算符)
inline pointer operator->() const { return &func(*this->source_it); }
- 计算转换后的值,并返回指针。
3.3 operator[](随机访问)
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<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())
};
}
- 创建 begin 和 end 的 transform_iterator。
5.2 const 版本
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) {
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_iterator(begin()和end())。
这种模式适用于 懒加载转换,避免显式创建新数据结构,提高效率。
到此这篇关于c++变换迭代器使用方法小结的文章就介绍到这了,更多相关c++变换迭代器使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论