如何让C++可变参数模板(参数包)匹配枚举类
替换混合类型模板参数的通用方案
问题核心
需要替换模板类型(如SYCL accessor)中的指定模板参数,但该模板的参数列表同时包含类型参数(如int)和非类型参数(如枚举类实例Animal::Fox)。直接使用class...作为参数包无法匹配枚举类这类非类型参数,而显式列举所有枚举类型又会导致代码通用性极差。
解决方案:C++17 auto... 模板参数包
C++17引入的auto...模板参数包可以匹配任意类型的非类型模板参数(包括枚举值、整数、指针等),结合类型参数即可写出完全通用的参数替换模板。
修改后的完整代码
#include <type_traits> enum class Animal { Fox, Gox }; enum class Food { Gruel }; template <typename T, int D, Animal A, Food F> struct Blah { }; template<typename, typename> struct apply_accessor {}; // 通用特化:匹配任意含「类型+int+任意非类型参数」的模板 template<template<typename, int, auto...> typename Acc, typename T1, typename T, int D, auto... Args> struct apply_accessor<Acc<T1, D, Args...>, T> { using type = Acc<T, D, Args...>; }; int main() { Blah<int,1,Animal::Fox,Food::Gruel> x; Blah<int,1,Animal::Gox,Food::Gruel> y; // 成功将Blah<int, ...>替换为Blah<float, ...>,保留其余参数 typename apply_accessor<decltype(x), float>::type z; static_assert(std::is_same_v<decltype(z), Blah<float,1,Animal::Fox,Food::Gruel>>); }
说明
template<typename, int, auto...>中的auto...会匹配所有后续的非类型模板参数,不管是Animal还是Food枚举类的实例,或是其他非类型参数(如整数、指针)。- 该方案无需为特定枚举类或非类型参数编写单独的特化版本,完全通用,解决了原代码中
class...无法匹配枚举类的问题。
内容的提问来源于stack exchange,提问作者David M. Rogers
相关产品推荐
相关产品推荐

