Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add common functionalities to structs by way of inheritance without having to explicitly initialize the base struct?

Tags:

c++

c++20

I have some structs that all have some common functionalities that I've put in an templated base class (here Foo<int>)

template<int I>
struct Foo
{
    void foo() { std::cout << "foo: " << I << '\n'; }
};

struct Bar : Foo<1>
{
    int i;
    int j;
};

Now when I initialize any of them I have to do it like so:

Bar b{{}, 1, 2};

And I would like to be able to do it like so:

Bar b{1, 2};

And also without the boilerplate of having to write a constructor. Is there some solution to this problem?

A similar question was asked here, however, this was over 7 years ago, so I was wondering if there were any developments since then.
Also, that question is marked duplicate of a question here, however this one is slightly different, as the base struct is not empty.
In addition, I'm not really trying to accomplish anything other than adding functionality to some structures, in a more declarative way, rather than repeating the definitions of all the common methods in each of them. So any solution that achieves that, by circumventing inheritance (apart from macros ideally ;D) would work as well.

like image 257
RKest Avatar asked Oct 16 '25 01:10

RKest


1 Answers

You can use designated initializers here:

Bar b{.i = 1, .j = 2};

You can also make the aggregate struct { int i; int j; } the first thing inherited from. Here are two ways you can make that happen:

template<int I>
struct Foo
{
    void foo() { std::cout << "foo: " << I << '\n'; }
};

struct BarBase {
    int i;
    int j;
};

struct Bar : BarBase, Foo<1> {};

Bar x{{.i = 1, .j = 2}};
Bar y{1, 2};
// This way also allows you to access the base.
// A common pattern for mixins, which is what Foo is
template<typename Base, int I>
struct Foo : Base
{
    void foo() { std::cout << "foo: " << I << '\n'; }
};

struct BarBase {
    int i;
    int j;
};

using Bar = Foo<BarBase, 1>;

Bar x{{.i = 1, .j = 2}};
Bar y{1, 2};
like image 85
Artyer Avatar answered Oct 18 '25 16:10

Artyer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!