在C ++中创建编译时键值映射

问题描述 投票:1回答:1

我已经尝试在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

我该如何进行这项工作?非常感谢:)

c++ templates metaprogramming key-value template-meta-programming
1个回答
0
投票

不要在不需要的地方编写模板元程序。试试这个简单的解决方案(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中运行。

© www.soinside.com 2019 - 2024. All rights reserved.