如何用C++ CUDA Thrust创建先偶后奇索引的迭代器?
若数组包含6个元素,该迭代器的索引序列应为[0, 2, 4, 1, 3, 5]。我了解counting_iterator和constant_iterator,但不知道如何创建上述迭代器,推测可能与transform_iterator有关,但具体实现方法不明。
嘿,这个需求确实可以用transform_iterator完美解决!核心思路就是用counting_iterator生成连续的基础索引(0到n-1),再通过一个自定义转换函数,把这些基础索引映射成你想要的「先偶后奇」序列。咱们一步步拆解实现:
核心转换逻辑
先明确转换规则:假设数组总共有n个元素,对于输入的基础索引i(范围0到n-1):
- 当
i在前半段(i < n/2)时,映射为偶数索引:2 * i - 当
i在后半段(i >= n/2)时,映射为奇数索引:2 * (i - n/2) + 1
比如n=6时,前半段i=0、1、2 → 0、2、4;后半段i=3、4、5 → 1、3、5,正好匹配你的需求。
用Boost库实现(兼容C++11及以上)
如果你习惯用Boost的迭代器工具,代码可以这么写:
#include <iostream> #include <boost/iterator/counting_iterator.hpp> #include <boost/iterator/transform_iterator.hpp> // 定义转换函数对象,保存数组总大小 class EvenFirstMapper { private: std::size_t total_size_; public: explicit EvenFirstMapper(std::size_t size) : total_size_(size) {} std::size_t operator()(std::size_t idx) const { if (idx < total_size_ / 2) { return 2 * idx; } else { // 计算后半段对应的奇数索引 return 2 * (idx - total_size_ / 2) + 1; } } }; int main() { constexpr std::size_t arr_size = 6; // 创建转换迭代器:counting_iterator生成0~5,再通过EvenFirstMapper转换 auto begin_iter = boost::make_transform_iterator( boost::counting_iterator<std::size_t>(0), EvenFirstMapper(arr_size) ); auto end_iter = boost::make_transform_iterator( boost::counting_iterator<std::size_t>(arr_size), EvenFirstMapper(arr_size) ); // 测试遍历 for (auto it = begin_iter; it != end_iter; ++it) { std::cout << *it << " "; } // 输出:0 2 4 1 3 5 return 0; }
用C++20标准库实现(更简洁)
如果你的环境支持C++20,用标准库的std::counting_iterator和范围视图会更清爽,不需要额外依赖Boost:
#include <iostream> #include <iterator> #include <ranges> int main() { constexpr std::size_t arr_size = 6; // 用lambda定义转换逻辑 auto even_first_map = [n = arr_size](std::size_t idx) { return idx < n/2 ? 2*idx : 2*(idx - n/2) + 1; }; // 生成索引序列:iota生成0~5,再通过transform转换 auto even_first_indices = std::views::iota(0u, arr_size) | std::views::transform(even_first_map); // 测试遍历 for (auto idx : even_first_indices) { std::cout << idx << " "; } // 输出:0 2 4 1 3 5 return 0; }
额外说明
如果你只是需要遍历数组的偶索引再奇索引,也可以分开两次遍历,但用transform_iterator的好处是能得到一个单一的迭代器序列,可以直接传给需要迭代器范围的标准算法(比如std::copy、std::for_each),代码会更统一优雅。
内容的提问来源于stack exchange,提问作者Duke Le
相关产品推荐
相关产品推荐

