问题
Is it possible (and if so, how) to generate a template pack from a indexed set of type traits so they can be used to instantiate a variant or a tuple?
#include <variant>
template<int n>
struct IntToType;
template<>
struct IntToType<0>
{
using type = int;
static constexpr char const* name = "int";
// Other compile-time metadata
};
template<>
struct IntToType<1>
{
using type = double;
static constexpr char const* name = "double";
// Other compile-time metadata
};
using MyVariant = std::variant<IntToType<???>::type...>; // something with make_integer_sequence and fold expression?
Or is it necessary to use the variant as input instead:
#include <variant>
using MyVariant = std::variant<int, double>;
template<int n>
struct IntToTypeBase
{
using type = std::variant_alternative_t<n, MyVariant>;
};
template<int >
struct IntToType;
template<>
struct IntToType<0>:IntToTypeBase<0>
{
static constexpr char const* name = "int";
// Other compile-time metadata
};
template<>
struct IntToType<1>:IntToTypeBase<1>
{
static constexpr char const* name = "double";
// Other compile-time metadata
};
or even roll your own variant
, which accepts a set of traits instead of a plain list of type:
template<class IntegerType, template<auto> class Traits, size_t LastIndex>
class Variant;
回答1:
You could do:
#include <variant>
template<int n>
struct IntToType;
template<>
struct IntToType<0>
{
using type = int;
static constexpr char const* name = "int";
// Other compile-time metadata
};
template<>
struct IntToType<1>
{
using type = double;
static constexpr char const* name = "double";
// Other compile-time metadata
};
// replace NUMBER_OF_TYPES
template <typename T=std::make_index_sequence<NUMBER_OF_TYPES> >
struct make_my_variant;
template <size_t... indices>
struct make_my_variant<std::index_sequence<indices...> > {
using type = std::variant<typename IntToType<indices>::type...>;
};
using MyVariant = typename std::make_my_variant<>::type;
Note to find the typename as a string literal, you could just use typeid(TYPE).name()
. You may need to demangle this name, if you wish; you can use your compiler-specific demangler function (I think MSVC doesn't mangle type names, but on GCC you would use abi::__cxa_demangle
in <cxxabi.h>
header.)
来源:https://stackoverflow.com/questions/64505297/create-template-pack-from-set-of-traits