コンパイル時に整数を別の整数にマップする必要があるという問題があります。基本的に、コンパイル時に相当するものが必要です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
で に関連付けられた値を返しkey
ますStaticMap
。key
が見つからない場合は、default_value
が返されます。
一般に、キーと値のペアの数は 2 を超える制限によって制限されstatic_map
ますlookup
。
また、C++03 言語構造の使用に制限されているため、C++11 も外部ライブラリの依存関係もありません。
以下のnmと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;
}