3

I am trying to init a static array in a function.

int query(int x, int y) {
    static int res[100][100]; // need to be initialized to -1
    if (res[x][y] == -1) {
        res[x][y] = time_consuming_work(x, y);
    }
    return res[x][y];
}

How can I achieve this?

7
  • You may want to learn about for loops. Commented Jul 27, 2019 at 13:52
  • 2
    @Hyperbola You could just use a static boolean variable, to guard the initialization performed by a double for loop... :) EDIT: Oh, please check bolov's answer, which uses a λ to initialize the array..! Commented Jul 27, 2019 at 14:06
  • 1
    @gsamaras Thanks, a lambda is so amazing! I have never thought about using lambda like this. Commented Jul 27, 2019 at 14:11
  • 1
    A lambda can also be useful to initialize a const variable: stackoverflow.com/questions/46345151/… Commented Jul 28, 2019 at 9:07
  • 1
    @bolov, you are correct. I intended to only give a hint. It seems like homework after all. But if that were "hint 1", then "hint 2" would have been gsamaras comment, to use a static boolean as a guard. That's where I was going, eventually. Commented Jul 28, 2019 at 21:28

4 Answers 4

7

First of all, I strongly recommend moving from C arrays to std::array. If you do this you can have a function to perform the initialization (otherwise you can't, as a function cannot return C arrays):

constexpr std::array<std::array<int, 100>, 100> init_query_array()
{
    std::array<std::array<int, 100>, 100> r{};
    for (auto& line : r)
        for (auto& e : line)
            e = -1;
    return r;
}

int query(int x, int y) {
    static std::array<std::array<int, 100>, 100> res = init_query_array();

    if (res[x][y] == -1) {
        res[x][y] = time_consuming_work(x, y);
    }
    return res[x][y];
}

Another option, that I actually like more is to perform the init in a lambda:

int query(int x, int y) {
    static auto res = [] {
        std::array<std::array<int, 100>, 100> r;
        for (auto& line : r)
            for (auto& e : line)
                e = -1;
        return r;
    }();

    if (res[x][y] == -1) {
        res[x][y] = time_consuming_work(x, y);
    }
    return res[x][y];
}
Sign up to request clarification or add additional context in comments.

5 Comments

That λ approach is so pleasing for the eyes, and doesn't suffer from the overhead of an extra variable . . . :)
This is so great!!
Can you explain what is static auto res = [] {}() syntax ?
@deoncagadoes it's a lambda expression . And the () at the end calls the lambda that we just defined.
@deoncagadoes that is a immediatly invoked lambda en.cppreference.com/w/cpp/language/lambda
2

You can't do this. You need an explicit for loop and a flag to avoid initializing more than once:

int query(int x, int y) {
    static bool initilized = false;
    static int res[100][100]; // need to be initialized to -1
    if (!initilized) {
        initilized = true;
        for (int i = 0; i != 100; ++i) {
            for (int j = 0; j != 100; ++j) {
                res[i][j] = -1;
            }
        }
    }
    if (res[x][y] == -1) {
        res[x][y] = time_consuming_work(x, y);
    }
    return res[x][y];
}

Comments

1

You can do it for example the following way by means of introducing one more static variable

int query(int x, int y) {
    static bool initialized;
    static int res[100][100]; // need to be initialized to -1

    if ( not initialized )
    {
        for ( auto &row : res )
        {
            for ( auto &item : row ) item = -1;
        }

        initialized = true;
    }        

    if (res[x][y] == -1) {
        res[x][y] = time_consuming_work(x, y);
    }
    return res[x][y];
}

Comments

1

You can use fill with std::array and a IIL(immediately invoked lambda) :

static std::array<std::array<int, 100>, 100> res = [] () {
     std::array<int, 100> default_arr;
     default_arr.fill(-1);

     std::array<std::array<int, 100>, 100> ret;
     ret.fill(default_arr);

     return ret;
}();

Comments

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.