2

I have a class template which accepts another class template and an int as the template parameters. I would like to create one, shared two-dimensional array which will be accessible to all class instances as well as static public methods (so that its not bound to any specific instance, but the class). I would like the array to be initialised at compile time. I cannot really nail it down; I have been trying various options but always end up with an error...

Example:

template <const unsigned int x, const unsigned int dim>
class Class1<Class2<x>, dim> {
 private:
    static constexpr int multable[dim][dim] = initializeMultable();
 public:
    static constexpr const int(*initializeMultable())[dim] {
        static int result[dim][dim];
        for (unsigned int i = 0; i < dim; ++i) {
            for (unsigned int j = 0; j < dim; ++j) {
                result[i][j] = i + j // whatever
            }
        }
        return result;
    }

What is the proper way to initialise such an array at compile time?

This question is still open, as I mentioned in the comments the answer below does not compile.

maciek
  • 1,807
  • 2
  • 18
  • 30

1 Answers1

2

C arrays can't be returned from functions. Use std::array instead:

template <const unsigned int x, const unsigned int dim>
class Class1<Class2<x>, dim> {
 private:
    static constexpr auto multable = []{
        std::array<int[dim], dim> result{};
        for (unsigned int i = 0; i < dim; ++i) {
            for (unsigned int j = 0; j < dim; ++j) {
                result[i][j] = i + j // whatever
            }
        }
        return result;
    }();

 public:
    static constexpr auto initializeMultable() {
        return multable;
    }
};

Artyer
  • 31,034
  • 3
  • 47
  • 75
  • The local variable shouldn't be declared `static`. `constexpr` code can modify variables whose lifetime is bounded by the constexpr call, but is not allowed to have any side effects which survive past the end of the function call. – Ben Voigt May 18 '23 at 19:50
  • See https://eel.is/c++draft/expr.const#5.2 and https://eel.is/c++draft/expr.const#5.16 – Ben Voigt May 18 '23 at 19:54
  • @Artyer: Does not work, I get: `error: use of undeclared identifier 'initializeMultable' static constexpr auto multable = initializeMultable();` – maciek May 18 '23 at 20:16
  • I don't think I can place it at the end since my class has more `private` variables, used by regular class methods – maciek May 18 '23 at 20:40
  • 1
    @maciek Previous errors were because I had just copied your question's code replacing the array with `std::array`, but this still runs into issues because [you simply can't initialize a `static constexpr` data member by calling a `static constexpr` function](https://stackoverflow.com/q/11522399). Replaced it with a lambda, and your old public `initializeMultable` function can just copy the static data member. – Artyer May 18 '23 at 21:28
  • @Artyer : Unfortunately, this is still bugged: `error: implicit instantiation of undefined template 'std::array'` at: `std::array result{};`. – maciek May 18 '23 at 21:36
  • The above problem was solved with `#include ` However, the code still does not work, I get: `error: constexpr variable 'multable' must be initialized by a constant expression` at `static constexpr auto multable = []{` – maciek May 18 '23 at 21:51