Home > Software design >  Is it possible to use X-Macro with std::variant (or with template in general)?
Is it possible to use X-Macro with std::variant (or with template in general)?

Time:10-21

I hope to do the following using X-macro with c 17, but since template parameter does not support trailing comma, it does not work for the std::variant part. Is there someway around it?

#define LIST_OF_TYPES(X) \
  X(Type1)               \
  X(Type2)               \
  X(Type3)

#define MAKE_TYPE(name) class name {};
LIST_OF_TYPES(MAKE_TYPE)
#undef MAKE_TYPE

std::variant<
#define MAKE_VARIANT(name) name,
LIST_OF_TYPES(MAKE_VARIANT)
#undef MAKE_VARIANT
>

CodePudding user response:

Put the comma at the beginning and add a first element of some kind, whether it is relevant or not. One possibility:

template<template<typename...> class Tmpl, typename... Ts>
using specialization = Tmpl<Ts...>;

using my_variant = specialization<std::variant
    #define MAKE_VARIANT(name) ,name
    LIST_OF_TYPES(MAKE_VARIANT)
    #undef MAKE_VARIANT
>;

CodePudding user response:

Yes, there's a workaround:

#define EMPTY(...)
#define IDENTITY(...) __VA_ARGS__
#define IDENTITY2(...) __VA_ARGS__

std::variant<
#define MAKE_VARIANT(name) (,) name IDENTITY
IDENTITY2(EMPTY LIST_OF_TYPES(MAKE_VARIANT) () )
#undef MAKE_VARIANT
>

Without IDENTITY2(...) this expands to EMPTY(,) Type1 IDENTITY(,) Type2 IDENTITY(,) Type3 IDENTITY(). IDENTITY2 forces it to expand again, this time to Type1, Type2, Type3.

  • Related