You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:38:24