如何让类模板成员函数的参数类型依赖类模板参数值?
根据类模板参数选择成员函数的参数类型
要实现你需要的功能——让类模板成员函数的参数类型依赖模板布尔参数,且共用同一实现,可以借助C++的类型萃取工具来实现,下面是两种实用的写法:
方法一:定义条件类型别名(可读性优先)
通过std::conditional(需要包含<type_traits>头文件)定义一个依赖模板参数的类型别名,再用这个别名作为函数参数类型:
#include <memory> #include <type_traits> template <class T, bool plainPointer = true> class C { // 根据plainPointer的值决定参数类型:true用裸指针T*,false用shared_ptr<T> using ParamType = typename std::conditional<plainPointer, T*, std::shared_ptr<T>>::type; public: void f(ParamType x) { // 共用的实现逻辑 // 如果需要区分两种指针的行为,用C++17的if constexpr做编译期分支 if constexpr (plainPointer) { if (x) { // 裸指针需要判空 x->do_something(); } } else { x->do_something(); // shared_ptr无需手动判空 } // 如果操作逻辑完全一致,直接写通用代码即可 // x->common_operation(); } };
方法二:直接在参数中使用条件类型(紧凑写法)
如果不想单独定义类型别名,也可以直接把std::conditional的结果写在函数参数里:
#include <memory> #include <type_traits> template <class T, bool plainPointer = true> class C { public: void f(typename std::conditional<plainPointer, T*, std::shared_ptr<T>>::type x) { // 共用实现 x->common_operation(); } };
简化写法(C++14及以上)
C++14引入了std::conditional_t,可以替代typename std::conditional<...>::type,让代码更简洁:
// 方法一的简化版 using ParamType = std::conditional_t<plainPointer, T*, std::shared_ptr<T>>; // 方法二的简化版 void f(std::conditional_t<plainPointer, T*, std::shared_ptr<T>> x) { ... }
注意事项
- 如果实现中需要针对两种指针做不同操作,必须用
if constexpr(C++17特性),它会在编译期只保留符合条件的分支,避免出现“裸指针调用shared_ptr专属方法”这类编译错误。 - 只要两种指针类型支持相同的操作(比如
->运算符),通用实现部分可以完全复用,无需额外分支。
内容的提问来源于stack exchange,提问作者S.V
相关产品推荐
相关产品推荐

