为什么C++暂无变量模板模板参数?相关提案状态及替代方案有哪些
问题解答
1. 为什么C++当前没有支持变量模板模板参数/实参?
C++模板体系是逐步迭代完善的,早期设计模板模板参数时仅支持类模板作为入参,后续虽新增了别名模板的支持,但变量模板作为模板参数的语法设计并未纳入初始规划。此外标准委员会的特性优先级排序中,这类面向元编程场景的语法糖优先级低于并发、ranges、concepts等适用范围更广的特性,因此一直没有排入正式的标准落地计划。
2. 相关提案的状态是什么?
你提到的P2008R0号提案主题为「统一模板模板参数」,核心目标就是支持将变量模板、函数模板作为模板模板参数传入。目前该提案仍处于C标准委员会的评审修订阶段,尚未被纳入任何已发布的C标准(C20、C23均未收录),也暂未确认会纳入后续的C++26标准草案。
3. 可行的替代方案
目前有几种成熟的替代方案可以实现同等效果:
- 方案1:传递对应类模板:绝大多数变量模板都是对应类模板的
value别名,你可以直接传递对应的类模板,在接收端内部取::value即可,调整后的代码示例如下:
// 调整后的变量模板定义,接收类模板作为参数 template <template <typename> class MetaPredicate, typename T> constexpr bool has_predicate_v_ = requires { { MetaPredicate<T>::value } -> std::convertible_to<bool>; }; // 调用方式改为传类模板dummy_01 std::cout << std::boolalpha << has_predicate_v_<dummy_01, int> << '\n'; // 输出true
对应的count_if实现也可以按照同样逻辑调整:
template <typename Type, template <typename> class Predicate> struct count_if { // 内部遍历元素时调用Predicate<T>::value判断即可 inline static constexpr size_t value = /* 元编程逻辑实现 */; }; template <typename Type, template <typename> class Predicate> inline constexpr size_t count_if_v = count_if<Type, Predicate>::value; // 调用时传递类模板std::is_integral count_if_v<std::tuple<int, double, void, size_t, unsigned short>, std::is_integral>; // 计算结果为3
- 方案2:C++20泛型lambda封装:如果使用C++20及以上版本,可以把变量模板封装为泛型lambda传递,接收端直接调用lambda即可:
// 调用示例,lambda内部直接返回变量模板的结果 count_if_v<std::tuple<int, double, void, size_t, unsigned short>, []<typename T> { return std::is_integral_v<T>; }>;
- 方案3:宏包装适配:如果需要兼容旧标准的语法,也可以用宏做一层语法包装,自动把变量模板转换为对应的类模板调用,但这种方式会引入宏的副作用,非必要不推荐。
内容的提问来源于stack exchange,提问作者Desmond Gold
相关产品推荐
相关产品推荐

