1

I am new to C++ and in the process of learning. I have a matrix deftype:

using Matrix = std::array<std::array<T, COL>, ROW>;

I can initialize a constexpr matrix "manually" as such

constexpr Matrix<int, 2,2> mat{ {
        {{ 1,2 }},
        {{ 3, 4 } }
}};

This is not feasible for large examples of ROW,COL. Instead i would like to initialize it "programmatically"(i.e. through a loop or similar) with a function fill_entry so that mat[i][j] takes value fill_entry(i,j) and fill_entry is something like

 template<T>
constexpr T fill_entry(T This_object_has_type_T,int i , int j).

What is a correct way to do this? I use C++17

1 Answer 1

4

You can use an immediately invoked lambda:

constexpr auto mat = []() {
    Matrix<int, 2, 2> result{};

    int value = 1;
    for (std::size_t i = 0; i < result.size(); ++i) {
        for (std::size_t j = 0; j < result[0].size(); ++j) {
            result[i][j] = value;
            ++value;
        }
    }

    return result;
}();

If you need to initialize multiple variables like this, you can make this into a function:

template<typename T, std::size_t Rows, std::size_t Cols>
constexpr Matrix<T, Rows, Cols> create_mat() {
    Matrix<T, Rows, Cols> result{};

    int value = 1;
    for (std::size_t i = 0; i < result.size(); ++i) {
        for (std::size_t j = 0; j < result[0].size(); ++j) {
            result[i][j] = static_cast<T>(value);
            ++value;
        }
    }

    return result;
}

and call it as create_mat<int, 2, 2>().

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Your solution does not work with my compiler (MS visual studio), it gives me the error when caling create_mat that "constexpr function create_mat cannot result in a constant expression". I found out that your solution works if i change from C++17 to the option "latest" which i guess means c++ 20. Which compiler/OS did you test yours on?
@Conformal You're right, it doesn't compile with C++17 (but does with C++20), the reason is result needs to be value initialized, so changing result to result{} should work (it works on godbolt). I also fixed a few typos in my answer.
@IlCapitano I have a very similar issue that I can't get working. Instead of using Matrix; I'm trying to use tuple. I'm using the same approach but it won't compile: godbolt.org/z/c7bxa8zhP . Any ideas?
@AlexD Looks like std::tuple::operator= is constexpr only since C++20, so it won't work in C++17.
@IlCapitano your wisdom is much appreciated

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.