元函数将类型转换为整数,反之亦然

文森特

typeid允许分配一个唯一的std::type_index在运行时每个类型。我想做同样的事情,静态地使用两个元函数:

// Get a unique integral number associated with the provided type
template <class T>
struct encode_type
{
    using type = T;
    static constexpr std::size_t value = /* Metaprogramming magic */;
};

// Get the type uniquely associated with the provided value
template <std::size_t V>
struct decode_type
{
    static constexpr std::size_t value = V;
    using type = /* Metaprogramming magic */;
};

有没有办法在C ++ 11中做到这一点?

格子呢骆驼

这是一个可能与GCC 5.2和Clang 3.7“兼容”的解决方案。

我使用菲利普·罗森(FilipRoséen)的Constexpr Meta-Container进行了一些细微改动。正如TC指出的那样,这可能会在将来变得不正确,因此此解决方案在生产代码中完全不合理,但目前还是很酷的。我什至不确定这是否100%符合标准。

// This is our meta-container
using TypeMap = atch::meta_list<class A>;

// Get a unique integral number associated with the provided type
template <class T>
struct encode_type
{
    using type = T;
    // Push T into the container and store the pre-push size
    //( requires slight change to Filip's code)
    static constexpr std::size_t value = TypeMap::push<T>();
};

// Get the type uniquely associated with the provided value
template <std::size_t V>
struct decode_type
{
    static constexpr std::size_t value = V;
    // Get the type at index V
    // (requires a small helper function addition)
    using type = decltype(TypeMap::at<V>());
};

我对原始代码所做的更改:

template<class T, class H = meta_list, std::size_t Size = counter::value()>
static constexpr std::size_t push (
  size_type = push_state<
    typename H::template value<>::template push<T>::result
  > ()
) { return Size; } 

我修改atch::meta_list::push在推送之前返回meta容器的大小我使用带有默认参数的模板参数来确保在推入之前计算大小。

template<size_type Idx, class H = meta_list>
static constexpr auto at () -> typename H::template value<>::template at<Idx>::result;

我添加了一个小的decltype辅助函数,atch::meta_list以隐藏所有依赖的名称混乱。


一些测试代码:

int main () {
    std::array<int, 4> encoded { 
        encode_type<int>::value,
        encode_type<double>::value,
        encode_type<std::string>::value,
        encode_type<float>::value
    };
  
  std::cout << "Encoding: ";
  for (auto i : encoded) std::cout << i << ", ";
  std::cout << std::endl;
  
  std::array<std::type_index, 4> decoded {
      typeid(decode_type<0>::type),  
      typeid(decode_type<1>::type),
      typeid(decode_type<2>::type),
      typeid(decode_type<3>::type),
  };
  
  std::cout << "Decoding: ";
  for (auto i : decoded) std::cout << i.name() << ", ";
  std::cout << std::endl;
}

Clang和GCC都发出了一堆警告,但它们都“起作用”!

Clang编译,运行和输出

编码:0、1、2、3,

解码:i,d,NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE,f,

GCC编译,运行和输出

编码:0、1、2、3,

解码:i,d,NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE,f,


也许您最好通过预处理步骤...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将整数转换为指针,反之亦然

将括号从{转换为},反之亦然

如何在不使用任何内置函数的情况下将整数转换为 c 字符串,反之亦然以及其他数据类型?

将正负号整数转换为无符号(反之亦然)

Java-将小时数(双精度)转换为分钟数(整数),反之亦然

编年史队列:将循环整数转换为时间戳,反之亦然

Java数据类型转换为Swift,反之亦然

如何将NSDictionary转换为NSData,反之亦然?

将当地时间转换为UTC,反之亦然

如何将AnsiString转换为TBytes,反之亦然?

Dart:将Observable转换为Future,反之亦然?

将密钥转换为字符串,反之亦然

将字节转换为 dart 中的位,反之亦然

将HTML实体转换为Unicode,反之亦然

如何将实体转换为 dto,反之亦然?

将mysql regex转换为java regex(反之亦然)

将厘米转换为英尺和英寸,反之亦然?

将像素位置转换为纬度/经度,反之亦然

将XDocument转换为XmlDocument,反之亦然

将向量的索引转换为其内容,反之亦然

如何将CLOB转换为图像,反之亦然?

ByteBuffer - 将 long 转换为 char 数组,反之亦然

将 Eigen::SparseMatrix 转换为 cuSparse,反之亦然

将熊猫数据框转换为字典,反之亦然

BASH同时将大写转换为小写,反之亦然

使用 VMTK 将 VTK 转换为 STL,反之亦然

将网格上的总体转换为坐标,反之亦然

将Armadillo矩阵转换为Eigen MatriXd,反之亦然

C ++ | 将int转换为byte [4],反之亦然