【发布时间】:2013-05-05 15:27:46
【问题描述】:
我有一个问题,我需要在编译时将一个整数映射到另一个整数。基本上,我需要std::map<int,int> 的编译时等价物。如果在地图中找不到键,我想返回一个默认值。
我想使用的界面:
template<unsigned int default_value,
unsigned int key0, unsigned int value0,
unsigned int key1, unsigned int value1,
...>
struct static_map
{
...
};
template<unsigned int key, typename StaticMap>
struct lookup
{
static unsigned int value = ...
};
lookup 返回与StaticMap 中的key 关联的值。如果找不到key,则返回default_value。
一般来说,键/值对的数量会受到一定的限制 > 2。构建 static_map 和 lookup 的最佳方法是什么?
我还应该提到,我仅限于使用 C++03 语言结构,因此没有 C++11,也没有外部库依赖项。
这是我得到的解决方案,灵感来自 n.m.和 DyP 的回答如下:
#include <iostream>
template<unsigned int k, unsigned int v>
struct key_value
{
static const unsigned int key = k;
static const unsigned int value = v;
};
template<typename Head, typename Tail = void>
struct cons
{
template<unsigned int key, unsigned int default_value>
struct get
{
static const unsigned int value = (key == Head::key) ? (Head::value) : Tail::template get<key,default_value>::value;
};
};
template<typename Head>
struct cons<Head,void>
{
template<unsigned int key, unsigned int default_value>
struct get
{
static const unsigned int value = (key == Head::key) ? (Head::value) : default_value;
};
};
template<unsigned int default_value,
unsigned int key0, unsigned int value0,
unsigned int key1, unsigned int value1,
unsigned int key2, unsigned int value2,
unsigned int key3, unsigned int value3,
unsigned int key4, unsigned int value4,
unsigned int key5, unsigned int value5,
unsigned int key6, unsigned int value6,
unsigned int key7, unsigned int value7>
struct static_map
{
template<unsigned int key>
struct get
{
typedef cons<
key_value<key0,value0>,
cons<
key_value<key1,value1>,
cons<
key_value<key2,value2>,
cons<
key_value<key3,value3>,
cons<
key_value<key4,value4>,
cons<
key_value<key5,value5>,
cons<
key_value<key6,value6>,
cons<
key_value<key7,value7>
>
>
>
>
>
>
>
> impl;
static const unsigned int value = impl::template get<key,default_value>::value;
};
};
template<unsigned int key, typename StaticMap>
struct lookup
{
static const unsigned int value = StaticMap::template get<key>::value;
};
int main()
{
typedef static_map<13,
0, 0,
1, 10,
2, 20,
3, 30,
4, 40,
5, 50,
6, 60,
7, 70
> my_static_map;
std::cout << "0 maps to " << lookup<0, my_static_map>::value << std::endl;
std::cout << "1 maps to " << lookup<1, my_static_map>::value << std::endl;
std::cout << "2 maps to " << lookup<2, my_static_map>::value << std::endl;
std::cout << "3 maps to " << lookup<3, my_static_map>::value << std::endl;
std::cout << "4 maps to " << lookup<4, my_static_map>::value << std::endl;
std::cout << "5 maps to " << lookup<5, my_static_map>::value << std::endl;
std::cout << "6 maps to " << lookup<6, my_static_map>::value << std::endl;
std::cout << "7 maps to " << lookup<7, my_static_map>::value << std::endl;
std::cout << "100 maps to " << lookup<100, my_static_map>::value << std::endl;
return 0;
}
【问题讨论】:
-
@user93353:此问题与您链接的问题无关。
-
@DyP:是的,我需要类似 boost 的 MPL 地图。不幸的是,我不能依赖 MPL,所以我想了解它的实现。
-
@JaredHoberock 哎呀,MPL 映射适用于类型。可能不是你要找的..
-
限制是固定的还是需要多张不同大小的地图?
标签: c++ template-meta-programming