当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《元函数将类型转换为整数,反之亦然》经验,为你挑选了1个好方法。

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

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

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

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



1> TartanLlama..:

这是一个可能与GCC 5.2和Clang 3.7"协同工作"的解决方案.

我使用FilipRoséen的Constexpr Meta-Container进行了一些细微的改动.正如TC指出的那样,未来可能会形成这种形式,因此这种解决方案在生产代码中是完全不合理的,但现在它还很酷.我甚至不确定这是否符合100%标准.

// This is our meta-container
using TypeMap = atch::meta_list;

// Get a unique integral number associated with the provided type
template 
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();
};

// Get the type uniquely associated with the provided value
template 
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());
};

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

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

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

template
static constexpr auto at () -> typename H::template value<>::template at::result;

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


一些测试代码:

int main () {
    std::array encoded { 
        encode_type::value,
        encode_type::value,
        encode_type::value,
        encode_type::value
    };

  std::cout << "Encoding: ";
  for (auto i : encoded) std::cout << i << ", ";
  std::cout << std::endl;

  std::array 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,


也许你会在预处理步骤中做得更好......

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有