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.
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};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With