如何限定模板参数为BaseDicModel的派生类?
限定模板仅接受BaseDicModel派生类的实现方法
要把getDictionary模板限定为只接受BaseDicModel的派生类作为参数,C++里有几种实用的方案,根据你的编译器版本选择即可:
1. 编译期断言(static_assert)—— 直观明了的错误提示
这种方式能在编译阶段直接抛出清晰的错误信息,让使用者立刻知道哪里错了:
#include <type_traits> class BaseDicModel {}; template<typename T> T getDictionary() { // 强制检查T是否是BaseDicModel的派生类(包括基类本身) static_assert(std::is_base_of<BaseDicModel, T>::value, "模板参数必须是BaseDicModel的派生类"); // 这里写你的SQL查询和对象构造逻辑 return T{}; } // 测试用的合法派生类 class UserDictionary : public BaseDicModel {}; int main() { auto validDic = getDictionary<UserDictionary>(); // 正常编译 // auto invalidDic = getDictionary<int>(); // 编译报错,触发static_assert的提示 return 0; }
2. C++20 概念(Concepts)—— 最优雅的语法
如果你的项目支持C++20,用概念来约束模板参数是最直观的写法,代码可读性拉满:
#include <concepts> class BaseDicModel {}; // 定义一个概念,明确要求T必须是BaseDicModel的派生类 template<typename T> concept DicModelType = std::derived_from<T, BaseDicModel>; // 直接用概念约束模板参数 template<DicModelType T> T getDictionary() { // 原有SQL查询逻辑 return T{}; } class OrderDictionary : public BaseDicModel {}; int main() { auto validDic = getDictionary<OrderDictionary>(); // 合法 // auto invalidDic = getDictionary<float>(); // 编译报错,不符合概念约束 return 0; }
3. SFINAE 方式(兼容C++11及以上)
如果你的编译器版本较老,用enable_if的SFINAE技巧也能实现,只是错误提示不如前两种清晰:
#include <type_traits> class BaseDicModel {}; // 通过enable_if仅当条件满足时才生成有效模板 template<typename T, typename = std::enable_if_t<std::is_base_of<BaseDicModel, T>::value>> T getDictionary() { // 原有SQL查询逻辑 return T{}; } class ProductDictionary : public BaseDicModel {}; int main() { auto validDic = getDictionary<ProductDictionary>(); // 正常编译 // auto invalidDic = getDictionary<std::string>(); // 编译报错,找不到匹配的函数 return 0; }
内容的提问来源于stack exchange,提问作者faspowa
相关产品推荐
相关产品推荐

