1

I am looking to make this snippet more brief given there's a better way(s).

There's a pure virtual base class which is implemented by the Z and X child classes, which are both owned by class A.

A determines which method (one, two) gets invoked on which object (Z, X) based on what's passed in. The logic is the same when it comes to invoking which method based on the parameters however the only difference is the object that gets invoked on.

Instead of 'repeating' the steps by adding an if condition per object, is there a better way where I could maybe store a reference of the desired object's method which could get invoked inside foo?

class Base
{
    public:
    virtual void one() = 0;
    virtual void two() = 0;
};

struct Z : public Base
{
    void one() override
    {
        printf ("Zone\n");
    }
 
    void two() override
    {
        printf ("Ztwo\n");
    }
};

struct X : public Base
{
    void one() override
    {
        printf ("Xone\n");
    }

    void two() override
    {
        printf ("Xtwo\n");
    } 
};

class A
{
    Z z;
    X x;

    public:
    void foo(bool enableZ, bool enableX, bool runOne)
    {
        if (enableZ)
        {
            if (runOne)
            {
                z.one();
            }
            else            
            {
                z.two();
            }
        }
        else    // enableX
        {
            if (runOne)
            {
                x.one();
            }
            else
            {
                x.two();
            }
        }
    }
};

(I tried using function pointer but it didn't work). Perhaps something like the following where the decision on which object to inoke on has already been made? (though it errors out!)

void foo()
{
 Base* base = enableZ ? &z : &x;  // nope!
 if (runOne)
 {
   base->one();
 }
 else
 {
    base->two();
 }
}
xyf
  • 664
  • 1
  • 6
  • 16

1 Answers1

1

I am not sure if my following answer shortens your code snippet or not, but you can definitely achieve multiple dispatch in C++ with a map of std::function's.

std::map<std::pair<bool, bool>, std::function<void(void)>> foo_map = {
  {{true, true}, [&]() { z.one(); }},
  {{true, false}, [&]() { z.two(); }},
  {{false, true}, [&]() { x.one(); }},
  {{false, false}, [&]() { x.two(); }},
  };

void foo(bool enableZ, bool runOne) { foo_map.at({enableZ, runOne})(); }
wu1meng2
  • 71
  • 6