You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:34:56