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

如何编写C++ Concept以要求函数模板需传入枚举值作为模板参数?

问题解答

需求可行性

完全可行,借助C++20的Concept特性可以实现对这类类型的约束。

现有实现的问题分析

第一种实现的错误原因

你尝试用约束变量n作为模板参数,但n是运行时变量,而模板参数要求必须是编译期常量,因此编译器报错“Constraint variable 'n' cannot be used in an evaluated context”,这是C++模板参数的基本规则限制。

第二种实现的错误原因

std::declval<notification_t>()返回的是notification_t类型的右值对象,但notifiable_type::notification的模板参数是枚举值(非类型参数),而非枚举类型。你这里相当于把类型当作模板参数传递,与目标函数模板的参数要求不匹配,因此约束不满足。

正确的Concept实现

#include <concepts>
#include <type_traits>

enum class categories { 
  t1, 
  t2 
};

struct notifiable_type {
  template<categories category>
  auto notification() {}
};

template<typename NotifiableT, typename EnumT>
concept Notifiable = std::is_enum_v<EnumT> && requires(NotifiableT t) {
  // 验证存在以EnumT枚举值为模板参数的notification成员函数,且返回void
  template<EnumT E>
  { t.template notification<E>(); } -> std::same_as<void>;
};

// 验证约束生效
static_assert(Notifiable<notifiable_type, categories>);

auto main() -> int {
  notifiable_type().notification<categories::t1>();
  return 0;
}

实现说明

  1. 用std::is_enum_v<EnumT>确保第二个模板参数是枚举类型;
  2. 在requires表达式中使用模板化的约束子句,声明一个类型为EnumT的非类型模板参数E;
  3. 检查调用t.template notification<E>()是否合法,且返回值类型为void,以此验证目标类型拥有符合要求的成员函数模板。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:42:23