我已经尝试在C ++中创建一个编译时简单键值映射。我正在使用/std:c++11
进行编译。(使用IAR编译器嵌入代码,目前仅支持cpp ++ 11)
我已经学习了一些有关元编程的知识。
[我不希望我的地图具有默认值,如果找不到密钥的话,像这样的帖子:How to build a compile-time key/value store?
我想获取编译器错误,如果在我的代码中我试图获取未存储在映射中的值。
这是我所做的:
#include <iostream>
template <int kk, int vv>
struct KeyValue
{
static const int k = kk, v = vv;
};
// Declaration
template <typename kv, typename...>
struct CompileTimeMap;
// Recursive Definition
template<typename kv, typename... rest>
struct CompileTimeMap<kv, rest...>
{
template<int k_input>
struct get
{
static const int val = (k_input == kv::k) ? kv::v : CompileTimeMap<rest...>::get<k_input>::val;
};
};
// Base Definition
template <typename kv>
struct CompileTimeMap<kv>
{
template<int k_input>
struct get
{
static const int val = (k_input == kv::k) ? kv::v;
};
};
// ----------------------------- Main -----------------------------
typedef CompileTimeMap<KeyValue<10, 20>, KeyValue<11, 21>, KeyValue<23, 7>> mymap;
int main()
{
// This calles should be ok !! :)
std::cout << mymap::get<10>::val << std::endl;
std::cout << mymap::get<11>::val << std::endl;
std::cout << mymap::get<23>::val << std::endl;
// This line should resolve a compile error !! (there is no key of 33)
std::cout << mymap::get<33>::val << std::endl;
}
我收到以下错误:error C2131: expression did not evaluate to a constant
。
我该如何进行这项工作?非常感谢:)
不要在不需要的地方编写模板元程序。试试这个简单的解决方案(CTMap
代表编译时间图):
template <class Key, class Value, int N>
class CTMap {
public:
struct KV {
Key key;
Value value;
};
constexpr CTMap (const KV (&initialPairs)[N]) :
pairs {}
{
for (int i = 0; i < N; i++)
pairs[i] = initialPairs[i];
}
constexpr Value operator[] (Key key) const
{
for (auto kv : pairs) {
if (kv.key == key)
return kv.value;
}
throw "Key not found";
}
private:
KV pairs[N];
};
constexpr CTMap<int, int, 3> ctMap ({ { 10, 20 }, { 11, 21 }, { 23, 7 } });
static_assert (ctMap[10] == 20, "Error.");
static_assert (ctMap[11] == 21, "Error.");
static_assert (ctMap[23] == 7, "Error.");
// constexpr auto compilationError = ctMap[404];
如果取消注释最后一行(live demo),则会出现编译错误。编译器会将您定向到throw
行,从该行显而易见的失败原因。
注意,此代码需要C ++ 14,因为operator[]
使用for
循环。如果将实现更改为递归实现,它也将在C ++ 11中运行。