如何在可变参数模板类中定义带特定约束的函数类型?
解决方案:可变参数模板生成"前const引用+最后非const引用"的函数指针类型
要实现除最后一个参数为非const引用、其余均为const引用的函数指针类型,我们可以通过递归辅助模板拆分并处理参数包,具体实现如下:
完整代码示例
#include <iostream> #include <typeinfo> // 辅助模板:递归生成符合要求的函数类型 template<typename... Args> struct FnLastNonConstHelper; // 基础特化:仅单个参数时,直接生成非const引用参数的函数类型 template<typename T> struct FnLastNonConstHelper<T> { using function_type = void(T&); }; // 递归特化:多参数时,当前参数处理为const引用,剩余参数递归处理 template<typename First, typename... Rest> struct FnLastNonConstHelper<First, Rest...> { using function_type = void(const First&, typename FnLastNonConstHelper<Rest...>::function_type::parameter_type...); }; template<typename First, typename ...Rest> struct SomeClass { using Fn = void (*)(First&, Rest&...); using FnConst = void (*)(const First&, const Rest&...); // 基于辅助模板生成目标函数指针类型 using FnLastNonConst = typename FnLastNonConstHelper<First, Rest...>::function_type*; }; int main() { // 打印类型名(可通过c++filt -t解析) std::cout << typeid(SomeClass<int, int, double>::Fn).name() << std::endl; std::cout << typeid(SomeClass<int, int, double>::FnConst).name() << std::endl; std::cout << typeid(SomeClass<int, int, double>::FnLastNonConst).name() << std::endl; // 验证单个参数的边界情况 std::cout << "\n单个参数场景:\n"; std::cout << typeid(SomeClass<double>::FnLastNonConst).name() << std::endl; return 0; }
代码说明
- 辅助模板
FnLastNonConstHelper:- 单个参数场景:直接生成
void(T&)类型,确保唯一的参数为非const引用。 - 多参数场景:将第一个参数处理为
const First&,然后递归处理剩余参数包,通过function_type::parameter_type提取递归结果的参数列表,拼接成当前函数类型。
- 单个参数场景:直接生成
- 目标类型
FnLastNonConst:
在SomeClass中,将辅助模板生成的函数类型转换为指针类型,即可得到符合要求的函数指针声明。
验证结果
通过c++filt -t解析类型名后,输出如下:
void (*)(int&, int&, double&) void (*)(int const&, int const&, double const&) void (*)(int const&, int const&, double&) 单个参数场景: void (*)(double&)
完全符合需求:前N-1个参数为const引用,最后一个参数为非const引用,且支持任意数量的模板参数。
内容的提问来源于stack exchange,提问作者wesleydungan
相关产品推荐
相关产品推荐

