Date: Mon, 11 Apr 2022 16:31:56 +0100
On Mon, Apr 11, 2022 at 10:34 AM Marcin Jaczewski wrote:
> ```
> template<typename... Modifiers>
> class Laser
> {
> std::tuple<Modifiers...> _mod; //could be base classes
> void trigger()
> {
> (get<Modifiers>(_mod).apply(), ...);
> }
> };
> ```
I see how that would work, however then you wouldn't be able to deal
with a simple "Laser &" or "Laser *".
Instead of having simple non-template functions like:
void DoSomething(Laser &arg) { . . . }
void DoSomethingElse(Laser &arg) { . . . }
You would have to complicate it as follows:
template<typename... Modifiers>
void DoSomething(Laser<Modifiers...> &arg) { . . . }
template<typename... Modifiers>
void DoSomethingElse(Laser<Modifiers...> &arg) { . . . }
One of the main simplicities of diamond virtual inheritance is to be
able to work with a generic reference (or generic pointer). With your
solution though, we no longer have a simple "Laser &", we now have a
"Laser<Modifiers...> &". And since your template functions get
instantiated for every permutation and combination of 'Modifiers', any
static variables/objects inside those template functions are unique
for each instantiation. If you have a static mutex inside one of those
functions then you've now got multiple mutexes.
One of the benefits of "Continuity Methods" is that you don't need to
bring templates into it, you can just keep working with generic
pointers and generic references. Less surprises.
Also, there's the smaller convenience of not having to keep track of
the base classes when you make a code change. For example if you have:
struct Derived : Base1, Base2, Base3, Base4 {
void Func(void) continue
{
}
};
and then let's say later you change one of the bases from 'Base4' to
'SomeOtherBase', then you don't need to edit a line saying
"this->Base4::Func();" to "this->Base4::SomeOtherBase();".
Also as I mentioned in my PDF draft proposal, the compiler makes sure
that the same method will never be invoked more than once on the same
object (which is applicable to diamond inheritance).
> ```
> template<typename... Modifiers>
> class Laser
> {
> std::tuple<Modifiers...> _mod; //could be base classes
> void trigger()
> {
> (get<Modifiers>(_mod).apply(), ...);
> }
> };
> ```
I see how that would work, however then you wouldn't be able to deal
with a simple "Laser &" or "Laser *".
Instead of having simple non-template functions like:
void DoSomething(Laser &arg) { . . . }
void DoSomethingElse(Laser &arg) { . . . }
You would have to complicate it as follows:
template<typename... Modifiers>
void DoSomething(Laser<Modifiers...> &arg) { . . . }
template<typename... Modifiers>
void DoSomethingElse(Laser<Modifiers...> &arg) { . . . }
One of the main simplicities of diamond virtual inheritance is to be
able to work with a generic reference (or generic pointer). With your
solution though, we no longer have a simple "Laser &", we now have a
"Laser<Modifiers...> &". And since your template functions get
instantiated for every permutation and combination of 'Modifiers', any
static variables/objects inside those template functions are unique
for each instantiation. If you have a static mutex inside one of those
functions then you've now got multiple mutexes.
One of the benefits of "Continuity Methods" is that you don't need to
bring templates into it, you can just keep working with generic
pointers and generic references. Less surprises.
Also, there's the smaller convenience of not having to keep track of
the base classes when you make a code change. For example if you have:
struct Derived : Base1, Base2, Base3, Base4 {
void Func(void) continue
{
}
};
and then let's say later you change one of the bases from 'Base4' to
'SomeOtherBase', then you don't need to edit a line saying
"this->Base4::Func();" to "this->Base4::SomeOtherBase();".
Also as I mentioned in my PDF draft proposal, the compiler makes sure
that the same method will never be invoked more than once on the same
object (which is applicable to diamond inheritance).
Received on 2022-04-11 15:32:09