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“兼容”的解决方案。
我使用Filip RoséenConstexpr Meta-Container进行了一些细微的改动。作为T.C.指出,将来可能是made ill-formed,因此该解决方案在生产代码中完全不合理,但目前还是很酷的。我什至不确定这是否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都发出了一堆警告,但它们都“起作用”!
compiles, runs and outputs:

GCC compiles, runs and outputs:


也许您可以通过预处理步骤来更好...

关于c++ - 元函数将类型转换为整数,反之亦然,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34230174/

10-09 05:57
查看更多