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

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/

    10-15 02:20