如何实现继承类Bar仅在基类可被其默认构造时具备默认构造能力?
问题背景与实现需求
先看一段基础C++代码:
class Foo { public: Foo() = default; }; int main() { static_assert(std::is_default_constructible_v<Foo>); return 0; }
Foo拥有公有的默认构造函数,因此static_assert可以通过。若将public改为private,Foo无法被默认构造,static_assert不通过,这符合预期。
若将public改为protected,Foo仍无法在main中被默认构造,static_assert依旧不通过。但如果有类Bar继承自Foo,则Bar内部可以默认构造Foo,但std::is_default_constructible_v<Bar<Foo>>仍不通过——这合理但存在问题。
核心问题
能否构造一个继承自Foo的类Bar,使其包含特定的默认构造逻辑,且仅当Bar能默认构造T时,自身才具备默认构造能力?
换句话说,需要实现Bar使得以下代码通过编译:
#include <type_traits> class Foo { protected: Foo() = default; }; class Doo { protected: Doo() = delete; }; template <typename T> struct Bar : public T { // some implementation ... Bar() // some magical `requires` statement here ... : T() { // some very important logic here! }; }; int main() { static_assert(std::is_default_constructible_v<Bar<Foo>>); static_assert(!std::is_default_constructible_v<Bar<Doo>>); return 0; }
补充说明
- 说明1:若将上述代码中的
protected改为public,解决方案很简单:Bar的构造函数只需要求T具备默认构造能力即可。但Foo和Doo必须使用保护构造函数,因为它们不能被单独实例化。 - 说明2:该问题并不局限于构造函数,可扩展到任意成员函数。选择默认构造函数只是因为存在现成的类型特性
std::is_default_constructible_v。
内容的提问来源于stack exchange,提问作者lobelk
相关产品推荐
相关产品推荐

