jeudi 25 mai 2017

How to write a template to cast to a templatized type based on an integer / enum

I'd like to simplify the code I write in my application that handles mutiple data structure types but with a common header. Given something like this:

enum class MyType {
  Foo = 100,
  Bar = 200,
};

struct Hdr {
  MyType type;
};

struct Foo {
  Hdr hdr;
  int x;
  int y;
  int z;
};

struct Bar {
  Hdr hdr;
  double value;
  double ratio;
};

void process(const Foo *ptr)
{
  // process Foo here
}

void process(const Bar *ptr)
{
  // process Bar here
}

extern void *getData();

int main()
{
  const void *pv = getData();
  auto pHdr = static_cast<const Hdr *>(pv);
  switch (pHdr->type) {
    case MyType::Foo: process(static_cast<const Foo *>(pv)); break;
    case MyType::Bar: process(static_cast<const Bar *>(pv)); break;
    default: throw "Unknown";
  }
  return 0;
}

Ideally I'd like to replace the switch statement above with something like:

process(multi_cast<pHdr->type>(pv);

I'm perfectly okay with having to write statements like this to get it to work:

template<MyType::Foo>
const Foo *multi_cast(void *p)
{
  return static_cast<const Foo *>(p);
}

template<MyType::Bar>
const Bar *multi_cast(void *p)
{
  return static_cast<const Bar *>(p);
}

But I cannot write a template where the template parameter is a enum (or an int for that matter) Have I just looked at this for so long that I cannot see an answer? Or is there just no other way to do it?

Aucun commentaire:

Enregistrer un commentaire