C++20中如何获取参数包除最后一个元素外的所有元素?
C++20 获取参数包除最后一个元素的实现方案
一、转为tuple的简洁实现
利用C++20的模板lambda和std::index_sequence,可以快速提取参数包中除最后一个外的所有元素并构造tuple:
#include <tuple> #include <utility> template <typename... Args> auto foo(Args&&... args) { constexpr auto arg_count = sizeof...(Args); // 处理参数数量为0或1的边界情况 if constexpr (arg_count <= 1) { return std::tuple<>{}; } else { // 借助模板lambda生成前arg_count-1个元素的tuple return []<std::size_t... Is>(std::index_sequence<Is...>, auto&& temp_tuple) { return std::tuple(std::get<Is>(std::forward<decltype(temp_tuple)>(temp_tuple))...); }(std::make_index_sequence<arg_count - 1>{}, std::forward_as_tuple(std::forward<Args>(args)...)); } }
说明:
std::forward_as_tuple将参数包转为转发引用类型的tuple,避免不必要的拷贝;std::make_index_sequence<arg_count-1>生成从0到arg_count-2的索引序列;- 模板lambda通过
std::get<Is>提取tuple中对应位置的元素,最终构造出目标tuple。
二、不使用tuple直接转发元素
如果不需要构造tuple,只是想将前N-1个元素转发给其他函数,可以用同样的索引序列思路,直接完成转发:
#include <utility> // 示例:接收转发元素的目标函数 void process_elements(auto&&... elements) { // 处理转发来的元素 } template <typename... Args> auto foo(Args&&... args) { constexpr auto arg_count = sizeof...(Args); if constexpr (arg_count <= 1) { // 无元素需要转发,直接处理边界情况 return; } else { []<std::size_t... Is>(std::index_sequence<Is...>, auto&& temp_tuple) { // 直接将前N-1个元素转发给目标函数 process_elements(std::get<Is>(std::forward<decltype(temp_tuple)>(temp_tuple))...); }(std::make_index_sequence<arg_count - 1>{}, std::forward_as_tuple(std::forward<Args>(args)...)); } }
说明:
- 同样借助
std::forward_as_tuple临时存储参数包的转发引用; - 通过索引序列提取前N-1个元素,用
std::forward保持值类别(左值/右值),直接转发给目标函数; - 全程无额外tuple拷贝,效率更高。
内容的提问来源于stack exchange,提问作者Juergen
相关产品推荐
相关产品推荐

