Vin*_*ent 8 c++ templates types template-meta-programming c++11
在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 */;
};
Run Code Online (Sandbox Code Playgroud)
有没有办法在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>());
};
Run Code Online (Sandbox Code Playgroud)
我对原始代码所做的更改:
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; }
Run Code Online (Sandbox Code Playgroud)
我修改atch::meta_list::push为在推送之前返回元容器的大小.我使用带有默认参数的模板参数来确保在推送之前计算大小.
template<size_type Idx, class H = meta_list>
static constexpr auto at () -> typename H::template value<>::template at<Idx>::result;
Run Code Online (Sandbox Code Playgroud)
我添加了一个小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;
}
Run Code Online (Sandbox Code Playgroud)
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,
也许你会在预处理步骤中做得更好......
| 归档时间: |
|
| 查看次数: |
1559 次 |
| 最近记录: |