C++17/14下无lambda显式模板参数实现std::integer_sequence逻辑
在C17/C14中替代依赖lambda显式模板参数的代码实现
原始C++20代码
以下是依赖C++20 lambda显式模板参数的实现代码:
template<typename... Ts> struct Foo { std::tuple<Ts...> bars; auto get_labels(const std::array<std::size_t,sizeof...(Ts)>& indices) const { // 从bar的标签构造tuple return [&]<std::size_t... Is>(std::index_sequence<Is...>) { return std::make_tuple(std::get<Is>(bars).get_label(indices[Is])...); }(std::index_sequence_for<Ts...>{}); } };
兼容C17/C14的实现方案
C++17及更早版本不支持lambda显式模板参数,我们可以通过将lambda的逻辑提取为模板辅助函数或仿函数来替代,核心是利用模板参数推导与索引序列展开完成相同功能。
方案1:内部模板成员函数
直接在Foo结构体内部定义模板辅助函数,承接原lambda的逻辑:
#include <array> #include <tuple> #include <vector> template<typename... Ts> struct Foo { std::tuple<Ts...> bars; private: // 模板辅助函数,处理索引序列展开 template<std::size_t... Is> auto get_labels_impl(const std::array<std::size_t, sizeof...(Ts)>& indices, std::index_sequence<Is...>) const { return std::make_tuple(std::get<Is>(bars).get_label(indices[Is])...); } public: auto get_labels(const std::array<std::size_t, sizeof...(Ts)>& indices) const { return get_labels_impl(indices, std::index_sequence_for<Ts...>{}); } }; // 原Bar结构体与测试逻辑保持不变 template<typename T> struct Bar { std::vector<T> labels; auto get_label(std::size_t i) const { return labels.at(i); } }; int main() { auto foo = Foo<Bar<int>, Bar<float>>{{Bar<int>{{1,2,3}}, Bar<float>{{2.5,4.5,6.5}}}}; // 可根据需求添加输出逻辑 return 0; }
方案2:局部仿函数(适配C++14)
如果需要更紧凑的封装,可以定义局部仿结构体,通过其模板operator()实现索引展开:
#include <array> #include <tuple> #include <vector> template<typename... Ts> struct Foo { std::tuple<Ts...> bars; auto get_labels(const std::array<std::size_t, sizeof...(Ts)>& indices) const { // 局部仿结构体,封装展开逻辑 struct Impl { const Foo& self; const std::array<std::size_t, sizeof...(Ts)>& indices; template<std::size_t... Is> auto operator()(std::index_sequence<Is...>) const { return std::make_tuple(std::get<Is>(self.bars).get_label(indices[Is])...); } }; return Impl{*this, indices}(std::index_sequence_for<Ts...>{}); } }; // Bar结构体与main函数同方案1
说明
两种方案均通过将原lambda的模板参数逻辑转移到模板函数/仿函数中,利用C14及以上支持的std::index_sequence和std::index_sequence_for完成参数包展开,功能与原C20代码完全一致。
内容的提问来源于stack exchange,提问作者kc9jud
相关产品推荐
相关产品推荐

