从特征集创建模板包
Create template pack from set of traits
是否可以(如果可以,如何)从一组索引类型特征生成模板包,以便它们可用于实例化变体或元组?
#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?
或者是否有必要改用变体作为输入:
#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
};
甚至推出你自己的 variant
,它接受一组特征而不是简单的类型列表:
template<class IntegerType, template<auto> class Traits, size_t LastIndex>
class Variant;
你可以这样做:
#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;
请注意,要将类型名称查找为字符串文字,您可以只使用 typeid(TYPE).name()
。如果愿意,您可能需要删除此名称;你可以使用你的 compiler-specific demangler 函数(我认为 MSVC 不会破坏类型名称,但在 GCC 上你会在 <cxxabi.h>
header 中使用 abi::__cxa_demangle
。)
是否可以(如果可以,如何)从一组索引类型特征生成模板包,以便它们可用于实例化变体或元组?
#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?
或者是否有必要改用变体作为输入:
#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
};
甚至推出你自己的 variant
,它接受一组特征而不是简单的类型列表:
template<class IntegerType, template<auto> class Traits, size_t LastIndex>
class Variant;
你可以这样做:
#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;
请注意,要将类型名称查找为字符串文字,您可以只使用 typeid(TYPE).name()
。如果愿意,您可能需要删除此名称;你可以使用你的 compiler-specific demangler 函数(我认为 MSVC 不会破坏类型名称,但在 GCC 上你会在 <cxxabi.h>
header 中使用 abi::__cxa_demangle
。)