如何使用C++20 concepts在编译期校验策略类构造参数数量是否匹配
你可以直接为PolicyManager的构造函数添加std::constructible_from约束实现编译期校验,具体修改如下:
修正后的完整代码
#include <memory> #include <string> #include <concepts> class PolicyBase {}; class Policy1 : public PolicyBase { public: Policy1(int arg1, std::string arg2) {} }; class Policy2 : public PolicyBase { public: Policy2(int arg1) {} }; template<typename T> concept PolicyConcept = std::is_base_of_v<PolicyBase, T>; template<PolicyConcept T = Policy1, typename... InitArgs> class PolicyManager { public: // 新增constructible_from约束,检查T是否可以用当前参数包构造 PolicyManager(InitArgs&&... args) requires std::constructible_from<T, InitArgs&&...> { _policyState = std::make_unique<T>(std::forward<InitArgs>(args)...); } private: std::unique_ptr<T> _policyState; }; int main() { auto policy1 = std::make_unique<PolicyManager<Policy1>>(1, "2"); // 编译正常 auto policy2 = std::make_unique<PolicyManager<Policy2>>(1); // 编译正常 // auto policy1_err = std::make_unique<PolicyManager<Policy1>>(1); // 编译报错,参数不满足构造要求 }
关键修改说明
- 修复了原代码中策略类构造函数为私有、类定义末尾缺分号、
PolicyConept拼写错误的小问题 - 构造函数参数改为转发引用
InitArgs&&...,配合std::forward实现完美转发,避免不必要的拷贝开销 - 新增
requires std::constructible_from<T, InitArgs&&...>约束:std::constructible_from第一个参数为待构造的策略类类型,后续可变参数对应传入的构造参数类型,会在编译期直接校验参数是否合法,参数不匹配时会直接抛出约束不满足的错误,错误提示比默认的构造失败提示更清晰直观。
内容的提问来源于stack exchange,提问作者IdanB
相关产品推荐
相关产品推荐

