如何编写要求类具备noexcept构造函数的C++ Concept?
C++ Concept如何要求类拥有noexcept构造函数?
你给出的代码中,Ragdoll的构造函数未标记noexcept,但static_assert(cat<Ragdoll>)却通过了,核心问题是你在Concept中的noexcept表达式写法不符合约束要求。
你当前代码中noexcept(Cat{42})的实际作用
在requires子句中,noexcept(Cat{42})只是计算该表达式是否为noexcept的布尔值,但requires子句本身只检查表达式是否合法(比如Cat{42}能否正确构造对象),并不会将这个布尔结果作为Concept的约束条件。也就是说,不管构造函数是不是noexcept,只要Cat{42}是合法表达式,这一行就不会导致Concept不满足,这就是为什么你的static_assert会通过。
正确的Concept写法
要让Concept强制要求构造函数是noexcept的,需要使用嵌套的requires约束,明确将noexcept的检查结果作为约束条件,以下是两种可行写法:
写法一:在requires子句内添加嵌套requires约束
#include <concepts> class Ragdoll { int age_ = -1; public: Ragdoll(int age) /* noexcept */ : age_(age) {} int meow() const; int lose_hair(); }; template<typename Cat> concept cat = requires(Cat cat) { // 明确要求Cat{42}这个构造表达式是noexcept的 requires noexcept(Cat{42}); { cat.meow() } -> std::same_as<int>; }; // 此时如果Ragdoll构造函数无noexcept,static_assert会触发编译错误 static_assert(cat<Ragdoll>);
写法二:拆分约束,单独检查构造函数的noexcept属性
如果需要更清晰地分离构造函数约束和成员函数约束,可以拆分requires表达式:
#include <concepts> #include <utility> // 用于std::declval template<typename Cat> concept cat = requires(Cat cat) { { cat.meow() } -> std::same_as<int>; } && requires { // 使用std::declval避免构造临时对象,检查带int参数的构造函数是否noexcept requires noexcept(Cat(std::declval<int>())); };
修改后,当Ragdoll的构造函数未标记noexcept时,static_assert会按照预期触发编译错误。
优质Concept学习资源推荐
- 《C++20 Concepts in Practice》:专注于Concept的实际应用,涵盖基础语法、自定义Concept、标准库Concept的使用场景。
- C++标准文档Concepts章节:权威定义Concept的语义和规则,是深入理解的核心参考。
- C社区技术专栏的Concept系列:比如聚焦C20特性的技术内容,包含大量实例讲解,适合快速掌握实战技巧。
内容的提问来源于stack exchange,提问作者levzettelin
相关产品推荐
相关产品推荐

