Search code examples
c++polymorphismunions

Taking union as a method parameter


I wanna write a method taking different type of method pointers using argument polymorphism. I thought union will be a good idea in this situation. However, I don't know how to reference to the correct union instance using method argument.

#include <iostream>

union Method {
  struct {
    void (*a)();
    void (*b)(int);
  };
};

struct Item {
  char c;
  Method m;
};

int8_t menu_size = 0;
void add_item(Item menu[], Item item) {
  int8_t index = 0;
  bool exists = false;
  do {
    if (menu[index].c == item.c) exists = true;
    ++index;
  } while (menu[index].c == item.c);
  //
  if (exists) {
    menu[index - 1] = item;
  } else {  
    menu[menu_size] = item;
    ++menu_size;
  }
}

void hello();
void ret(int);

int main(void) {
  Item menu[2];

  add_item(menu, (Item){'h', &hello});
  add_item(menu, (Item){'r', &ret});

  menu[0].m();
  menu[1].m(5);

  return 0;
}

void hello() {
  std::cout << "Hello, World!\n";
}

void ret(int i) {
  std::cout << i << "\n";
}

Solution

  • You are correct, you "don't know how to reference to the correct union instance". That's how unions work. There's nothing about a union that indicates which instance of a union member is the one that's set. Some other, out of band, mechanism must be used to track that, and it is your responsibility to implement it, and manually record or track which union member you set. Some other variable, or flag, somewhere, whose value indicates which union member is set. This is not the only way to do this, of course, but is the simplest one. In any case it's your onus to correctly track of everything, here. It's a lot of work.

    Furthermore, C++ inherited unions from C, which does not have classes. And, in C++, unions that contain classes have further restrictions and gotchas, which really bring more hassles than they're worth.

    Fortunately, with modern C++, you will always use std::variants instead of union, which solves all of these problems, and does all of the hard work for you to make sure that everything in the union is done correctly, and type-safe.