C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Derived class's function invokes base class's function

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Sat, 16 Apr 2022 13:31:09 +0200
How I would see handling logic like this:
```
#include <tuple>
#include <stdexcept>

class ILaser
{
public:
    virtual void trigger() = 0;
};

template<typename... Parts>
class LaserImpl : public ILaser
{
    std::tuple<Parts...> _parts;
    int _heat = 0;

public:
    void trigger() final
    {
        float freq = 1;
        float power = 1;
        std::apply([&](auto... p){ ((void)p.update_freq(freq), ...);
}, _parts);
        std::apply([&](auto... p){ ((void)p.update_power(power), ...);
}, _parts);

        float charge = freq * power;
        float heat = charge * 0.321f;
        if (get_charge() > charge)
        {
            std::apply([&](auto... p){ ((void)p.use_charge(charge),
...); }, _parts);
            std::apply([&](auto... p){ ((void)p.heat_sink(heat), ...);
}, _parts);
            _heat += heat;
            if (_heat > 1000)
            {
                throw std::runtime_error("Boom!");
            }
        }
    }

    float get_charge()
    {
        return std::apply([&](auto... p){ return (p.get_charge() +
...); }, _parts);
    }
};

struct Nitrogen
{
    float get_charge() { return 0; }
    void update_freq(float& f) { }
    void update_power(float& f) { f *= 10; }
    void use_charge(float& f) { }
    void heat_sink(float& f) { }
};
struct PicoSecond
{
    float get_charge() { return 0; }
    void update_freq(float& f) { f /= 100; }
    void update_power(float& f) { }
    void use_charge(float& f) { }
    void heat_sink(float& f) { }
};
struct Battery
{
    float charge = 300;

    float get_charge() { return charge; }
    void update_freq(float& f) { }
    void update_power(float& f) { }
    void use_charge(float& f) { auto m = std::min(f, charge); if (m >
0){ f -= m; charge -= m;} }
    void heat_sink(float& f) { }
};
struct Heatsink
{
    float get_charge() { return 0; }
    void update_freq(float& f) { }
    void update_power(float& f) { }
    void use_charge(float& f) { }
    void heat_sink(float& f) { f -= 30; }
};

class Laser : public LaserImpl<Nitrogen, PicoSecond, Battery,
Heatsink, Heatsink>
{

};

int main() {
    Laser l;
    l.trigger();
    return l.get_charge();
}
```

https://godbolt.org/z/Tz3KnE4oq

sob., 16 kwi 2022 o 10:07 Frederick Virchanza Gotham via Std-Proposals
<std-proposals_at_[hidden]> napisaƂ(a):
>
> On 4/16/22, Thiago Macieira via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>
> > How about this use-case:
> >
> > bool Klass::func(int &r)
> > {
> > if (this->Base1::func(r))
> > return true;
> > if (this->Base2::func2(r))
> > return true;
> > r = 3;
> > return false;
> > }
>
>
> I'm considering presenting an array of function pointers to
> programmers so that they have that kind of control. Here's an
> approximation of how my 'precompiler' would do it:
>
> #include <array>
>
> class Laser {
> public:
> virtual bool Trigger(void)
> {
> return true;
> }
> };
>
> class Laser_Nitrogen : virtual public Laser {
> public:
> bool Trigger(void) override
> {
> static std::array<bool (Laser::*)(void), 1u> const methods {
> &Laser::Trigger };
>
> for ( auto const &method : methods )
> {
> (this->*method)();
> }
>
> return false;
> }
> };
>
> class Laser_PicoSecond : virtual public Laser {
> public:
> bool Trigger(void) override
> {
> static std::array<bool (Laser::*)(void), 1u> const methods {
> &Laser::Trigger };
>
> return true;
> }
> };
>
> class Laser_NitrogenPicoSecond : public Laser_Nitrogen, public
> Laser_PicoSecond {
> public:
> bool Trigger(void) override
> {
> static std::array<bool (Laser::*)(void), 3u> const methods {
> &Laser::Trigger,
> static_cast<bool (Laser::*)(void)>(&Laser_Nitrogen::Trigger),
> static_cast<bool (Laser::*)(void)>(&Laser_PicoSecond::Trigger)
> };
>
> for ( auto const &method : methods )
> {
> if ( (this->*method)() ) return true;
> }
>
> return false;
> }
> };
>
>
> This sample experimental code has two problems:
>
> (1) It invokes the base method twice on the same object
> (2) It doesn't compile because of casting to a virtual base
>
> but I think you see the idea of what I'm trying to do.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2022-04-16 11:31:20