如何用std::apply或折叠表达式处理元组中的非空指针元素
基于std::apply和折叠表达式的std::tuple指针遍历方案
针对你存储不同类型指针的std::tuple,这里提供两种基于标准库特性的遍历方案,无需手动编写模板循环:
方法一:std::apply + 折叠表达式
利用std::apply将tuple的元素展开为函数参数,再通过折叠表达式逐个处理每个指针:
#include <tuple> #include <iostream> int main() { int a = 10; double b = 3.14; std::tuple<int*, double*> foo{&a, nullptr}; // 包含一个空指针示例 // 定义你需要执行的操作:这里以打印非空指针指向的值为例 auto process_non_null_ptr = [](auto* ptr) { if (ptr != nullptr) { std::cout << "指针指向的值:" << *ptr << std::endl; } }; // 用std::apply展开tuple,折叠表达式遍历所有元素 std::apply([&](auto... args) { (process_non_null_ptr(args), ...); }, foo); return 0; }
这段代码中,std::apply会把foo里的每个指针作为参数传给lambda,(process_non_null_ptr(args), ...)是折叠表达式,通过逗号运算符依次对每个指针执行处理逻辑,自动处理tuple里的所有元素。
方法二:折叠表达式 + std::index_sequence
如果不想依赖std::apply,可以借助索引序列生成tuple的下标,再用折叠表达式访问每个元素:
#include <tuple> #include <iostream> #include <utility> // 通用处理函数,支持任意tuple和自定义操作 template <typename Tuple, typename Func> void process_tuple(Tuple&& tuple, Func&& func) { constexpr auto tuple_size = std::tuple_size_v<std::decay_t<Tuple>>; // C++20模板lambda生成索引序列 [&]<std::size_t... Indexes>(std::index_sequence<Indexes...>) { (func(std::get<Indexes>(tuple)), ...); }(std::make_index_sequence<tuple_size>{}); } int main() { int a = 20; double b = 6.28; std::tuple<int*, double*> foo{nullptr, &b}; // 传入自定义操作:打印非空指针的地址和值 process_tuple(foo, [](auto* ptr) { if (ptr != nullptr) { std::cout << "指针地址:" << ptr << ",指向的值:" << *ptr << std::endl; } }); return 0; }
这里通过std::make_index_sequence生成tuple的所有下标,再用折叠表达式(func(std::get<Indexes>(tuple)), ...)逐个取出元素并执行操作,同样能自动遍历整个tuple。
两种方案都支持任意类型的指针tuple,你只需要修改处理逻辑的lambda,就能替换成你需要的指定操作。
内容的提问来源于stack exchange,提问作者user877329
相关产品推荐
相关产品推荐

