c++ - C++编译时关联数组

标签 c++ templates

我认为这个问题可能更多是关于我对模板所做的任何琐碎事情而不是问题本身的弱点,但我想实现这样使用的模板类:

MyArray<std::string, 1, 3, 7> a;
a[1] = "hello";
a[3] = "world";
a[7] = "!";

// runtime error
// a[4] = "?";
在幕后,MyArray<std::string, 1, 3, 7>基本上等同于以下内容:
class C
{
  private:

    std::string _values[3];

  public:

    std::string & operator[](std::size_t index)
    {
      switch(index)
      {
        case 1: return _values[0];
        case 3: return _values[1];
        case 7: return _values[2];
        default: /* some error condition */
      }
    }
};
(当然,在现实生活中,与原始整数相比,我更可能使用枚举值,但这可以使示例代码最少。)
条件:
  • 如果在编译时未知索引,则需要工作
  • Access应该使用switch语句或类似的命令,而不是通过允许的键进行运行时线性搜索。
  • 不需要像std::unordered_map
  • 这样的具有潜在存储桶冲突的哈希图

    我也很乐意提供引用,该引用说明了如何编写这种模板代码。

    最佳答案

    好的,如果您不介意可能的巨大空间成本,则可以这样做:

    template<typename T, size_t Head, size_t... Tails>
    class MagicArray{
        std::array<T, 1 + sizeof...(Tails)> data;
        static constexpr size_t max(size_t a, size_t b) noexcept{
            return (a < b) ? b : a;
        }
        template<typename head, typename... tails>
        static constexpr size_t max(head a, tails... b) noexcept{
            if constexpr (sizeof...(b) == 0)
                return a;
            else
                return max(a, max(b...));
        }
        static constexpr size_t value_max = max(Head, Tails...);
        template<size_t addition, size_t I, size_t A, size_t... B>
        static constexpr size_t find() noexcept{
            if constexpr (I == A)
                return addition;
            else if constexpr (sizeof...(B) == 0)
                return value_max;
            else
                return find<addition + 1, I, B...>();
        }
        template<size_t... Is>
        static constexpr std::array<size_t, value_max + 1> generation(std::index_sequence<Is...>*) noexcept{
            return { (find<0, Is, Head, Tails...>())... };
        }
        static constexpr std::array<size_t, value_max + 1> mapping = generation((std::make_index_sequence<value_max + 1>*)nullptr);
    public:
        T& operator[](size_t index){
            if (index > value_max || mapping[index] == value_max)
                throw 0;
            else
                return data[mapping[index]];
        }
        T const& operator[](size_t index) const{
            if (index > value_max || mapping[index] == value_max)
                throw 0;
            else
                return data[mapping[index]];
        }
    };
    
    int main(){
        MagicArray<std::string, 1, 3, 7> a;
        a[1] = "Hello";
        a[3] = "World";
        a[7] = "!";
        a[9] = "Boooooooooooooooom!";
    }
    

    关于c++ - C++编译时关联数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63725780/

    相关文章:

    c++ - C++17模板参数中auto的优点

    c++ - 条件代码依赖于模板参数比较

    c++ - 我可以重载采用指针和非构造模板对象的运算符吗?

    c++ - emplace 和 unordered_map<?, std::array<?, N>>

    C++:在 mac osx 上将 std::cout 与 gcc 一起使用

    c++ - 运算符<< 重载解析 (C++)

    C++ 模板完全特化语法

    模板化类型的 C++ 模板特化

    C++ 嵌套 Lambda

    c++ - 没有用户代码的死锁