如何为C++ struct添加通用功能,无需显式初始化基struct与构造函数?
解决方案
针对空基类(仅含成员函数):C++20 [[no_unique_address]] 继承
你的模板基类Foo<I>没有非静态数据成员,属于空类。C++20引入的[[no_unique_address]]属性可让编译器优化掉空基类的存储空间,此时派生类会被视为仅包含自身数据成员的聚合体,直接用目标语法初始化即可,无需编写构造函数:
#include <iostream> template<int I> struct Foo { void foo() { std::cout << "foo: " << I << '\n'; } }; // 给基类添加[[no_unique_address]]属性 struct Bar : [[no_unique_address]] Foo<1> { int i; int j; }; int main() { Bar b{1, 2}; // 直接初始化,无需处理基类部分 b.foo(); // 正常调用基类方法 }
针对非空基类(含数据成员):默认构造函数+指定初始化器(C++20)
如果基类包含数据成员,只要基类通过类内默认初始化提供默认构造函数,就可以用C++20的指定初始化器跳过基类初始化步骤,直接初始化派生类成员:
template<int I> struct Foo { int val = I; // 默认初始化,自动生成默认构造 void foo() { std::cout << "foo: " << val << '\n'; } }; struct Bar : Foo<1> { int i; int j; }; int main() { Bar b{.i = 1, .j = 2}; // 指定初始化器,无需显式初始化基类 b.foo(); }
非继承方案:组合+[[no_unique_address]](C++20)
如果不想用继承,可采用组合方式,配合[[no_unique_address]]优化存储,再通过using声明导入基类方法,实现声明式添加通用功能:
#include <iostream> template<int I> struct Foo { void foo() { std::cout << "foo: " << I << '\n'; } }; struct Bar { [[no_unique_address]] Foo<1> foo_impl; int i; int j; // 导入基类方法,保持调用方式简洁 using foo_impl::foo; }; int main() { Bar b{1, 2}; // 直接初始化成员 b.foo(); // 调用方式与继承一致 }
补充:C++17及更早版本的限制
如果无法升级到C20,只能保留{{}, 1, 2}的初始化语法,或者用宏生成构造函数/推导指引,但你明确排除了宏,因此优先推荐使用C20的上述方案。
内容的提问来源于stack exchange,提问作者RKest
相关产品推荐
相关产品推荐

