Как инициализировать статический двумерный массив во время компиляции - PullRequest
2 голосов
/ 21 мая 2019

Я создал математическую многомерную структуру данных, рассмотрим следующий код:

template <class T, size_t ... Dims>
class ZAMultiDimTable
{
public:
    static constexpr size_t nDims = sizeof...(Dims);
    static constexpr size_t nElements = (... * Dims);
    static constexpr std::array<size_t, nDims> _indices = {Dims...};

    static size_t addIndices(size_t ind1,size_t ind2)
    {
        size_t ret = 0;
        size_t mul = 1;
        for (size_t i=0; i< nDims;++i)
        {
            ret+=mul*((ind1+ind2)%_indices[i]);
            ind1/=_indices[i];
            ind2/=_indices[i];
            mul*=_indices[i];
        }
        return ret;

    }

    friend inline const ZAMultiDimTable<T, Dims...>  operator*(const ZAMultiDimTable<T, Dims...>& l,const ZAMultiDimTable<T, Dims...>& r)
    {
        ZAMultiDimTable<T, Dims...> m;
        for(size_t i=0; i < nElements; ++i)
        {
            for (size_t j = 0; j < nElements; ++j)
            {
                m._table[addIndices(i,j)]+=l._table[i]*r._table[j];
            }
        }
        return m;
    }


private:
    std::array<T, nElements > _table;
};

функция addIndices() разбивает два комбинированных индекса на представление многомерных, а затем добавляет их.

Теперь я хочу создать статический 2d массив размером [nElements][nElements], который заменит функцию addIndices().Как мне сделать это элегантно во время компиляции?

1 Ответ

3 голосов
/ 21 мая 2019

Я хочу создать статический 2d массив с размером [nElements] [nElements], который заменит функцию "addIndices".Как мне сделать это элегантным способом во время компиляции?

Предложение: избегайте массивов в стиле C и используйте (на этот раз) std::array вместо.

Следуя этому предложению,Я предлагаю

1) заставить getIndices() a constexpr метод

2) определить следующее using (просто для упрощения вашей жизни в следующих пунктах) или что-то подобное (возможно, случшее имя)

using arr2D = std::array<std::array<std::size_t, nElements>, nElements>;

3) определить следующий static constexpr метод

static constexpr arr2D getIndices ()
 {
   arr2D  ret;

   for ( auto i = 0u ; i < nElements; ++i )
      for ( auto j = 0u ; j < nElements; ++j )
         ret[i][j] = addIndices(i, j);

   return ret;
 }

4) добавить следующий static constexpr член в класс (инициализируется следующим образом)

static constexpr arr2D inds { getIndices() };

Теперь у вас есть индексы в элементе constexpr, инициализированном во время компиляции.

...