Skip to content

Instantly share code, notes, and snippets.

@mosolovsa
Created November 6, 2020 09:12
Show Gist options
  • Save mosolovsa/7d4cf57c950cda7190cb44f464bb2920 to your computer and use it in GitHub Desktop.
Save mosolovsa/7d4cf57c950cda7190cb44f464bb2920 to your computer and use it in GitHub Desktop.
noway for virtuals
#include <iostream>
template <typename T> constexpr
void print_type() {
std::cerr << __PRETTY_FUNCTION__ << std::endl;
}
enum ETypes {
type1,
type2
};
struct Type1 {
static void func1() {
std::cerr << "Type1 Func1" << std::endl;
}
};
struct Type2 {
static void func1() {
std::cerr << "Type2 Func1" << std::endl;
}
};
// interface for functions, available to call via dispatch
namespace details {
template <typename T> struct Func1 {
static decltype(&T::func1) get() { return &T::func1; }
};
}
//TODO: abstact over enum and possible types via typelist?
struct SumType {
ETypes discr;
union {
Type1 typ1;
Type2 typ2;
};
// tag dispatching
template<template <typename T> class GETTER, typename R = void, typename... ARGS> R dispatch(ARGS... args) {
switch (discr) {
//TODO: generate dispatch function via typelist, each type will contain static tag to be compared with?
// foldexpression instead of typelist, C++17 only :(?
case (ETypes::type1): {
return (*GETTER<Type1>::get())();
}
case (ETypes::type2): {
return (*GETTER<Type2>::get())();
}
}
}
};
int main() {
SumType obj { ETypes::type2, Type1{} };
obj.dispatch<details::Func1>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment