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

如何编写C++ Concept确保序列所有索引的类型均已定义

问题描述

现有一套可特化的索引式类型特征(type trait),代码实现如下:

// Traits
template <size_t Idx, typename T>
struct nth_type;

template <size_t Idx, typename T>
using nth_type_t = typename nth_type<Idx, T>::type;

template <typename T>
struct num_types;

template <typename T>
inline constexpr size_t num_types_v = num_types<T>::value;

// Specialization
template <typename... Ts>
struct type_sequence {};

template <size_t Idx, typename... Ts>
struct nth_type<Idx, type_sequence<Ts...>>
  : std::type_identity<std::tuple_element_t<Idx, std::tuple<Ts...>>>
{};

template <typename... Ts>
struct num_types<type_sequence<Ts...>>
{
    static constexpr size_t value = sizeof...(Ts);
};

需要编写一个C++ Concept has_types,要求对于任意类型T,区间[0, num_types_v<T>)内的每一个索引Idx,typename nth_type<Idx, T>都合法且代表一个类型。无需手动枚举所有索引,达到如下示例的效果:

template<typename T>
concept has_types = requires {
  typename nth_type<0, T>;
  typename nth_type<1, T>;
  // ...
  typename nth_type<num_types<T> - 1, T>;
};
解决方案

可以借助std::index_sequence生成目标区间的所有索引,再通过折叠表达式(fold expression)逐个验证每个索引对应的nth_type是否合法,实现如下:

#include <utility> // 用于std::index_sequence和std::make_index_sequence
#include <type_traits> // 用于std::type_identity

// 辅助模板:验证给定索引序列中的所有索引对应的nth_type是否合法
template <typename T, size_t... Idxs>
constexpr bool all_nth_type_valid(std::index_sequence<Idxs...>) {
    // 折叠表达式:对每个Idx,检查requires { typename nth_type<Idxs, T>; }是否成立
    return (requires { typename nth_type<Idxs, T>; } && ...);
}

// 目标Concept
template <typename T>
concept has_types = all_nth_type_valid<T>(std::make_index_sequence<num_types_v<T>>{});

原理说明

  1. std::make_index_sequence<N>会生成一个包含0, 1, ..., N-1的索引序列,这里N就是num_types_v<T>,刚好覆盖需求的区间[0, num_types_v<T>)。
  2. 辅助函数all_nth_type_valid接收这个索引序列,通过折叠表达式(requires { ... } && ...),将每个索引对应的typename nth_type<Idx, T>合法性检查逻辑展开,只有所有检查都通过时,返回值才为true。
  3. has_types Concept直接依赖这个辅助函数的返回结果,满足需求。

内容的提问来源于stack exchange,提问作者maddisoj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:25:55