J'essaye d'initialiser un tableau statique dans une fonction.
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]; }
Comment puis-je y parvenir?
4 Réponses :
Vous pouvez le faire par exemple de la manière suivante en introduisant une autre variable statique
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]; }
Vous ne pouvez pas faire ça. Vous avez besoin d'une boucle for explicite et d'un drapeau pour éviter d'initialiser plusieurs fois:
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]; }
Tout d'abord, je recommande fortement de passer des tableaux C à std :: array
. Si vous faites cela, vous pouvez avoir une fonction pour effectuer l'initialisation (sinon vous ne pouvez pas, car une fonction ne peut pas renvoyer des tableaux C):
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]; }
Une autre option, que j'aime plus en fait, est de effectuer l'initialisation dans un lambda:
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]; }
Cette approche λ est si agréable pour les yeux et ne souffre pas de la surcharge d'une variable supplémentaire. . . :)
C'est tellement génial !!
Pouvez-vous expliquer ce qu'est la syntaxe static auto res = [] {} ()
?
@deoncagadoes c'est une expression lambda . Et le ()
à la fin appelle le lambda que nous venons de définir.
@deoncagadoes qui est un lambda immédiatement invoqué en.cppreference.com/w/cpp/language/ lambda
Vous pouvez utiliser fill
avec std :: array
et un IIL (immédiatement appelé 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; }();
Vous voudrez peut-être en savoir plus sur les boucles
for
.@donjuedo qui ne va pas initialiser un tableau statique.
@Hyperbola Vous pouvez simplement utiliser une variable booléenne statique, pour protéger l'initialisation effectuée par une boucle double for ... :) EDIT: Oh, veuillez vérifier les bolov answer , qui utilise un λ pour initialiser le tableau ..!
@gsamaras Merci, un lambda est tellement incroyable! Je n'ai jamais pensé à utiliser lambda comme ça.
Un lambda peut également être utile pour initialiser une variable
const
: stackoverflow.com/questions/46345151/...@bolov, vous avez raison. J'avais l'intention de ne donner qu'un indice. Cela ressemble à des devoirs après tout. Mais si c'était "hint 1", alors "hint 2" aurait été un commentaire gsamaras, pour utiliser un booléen statique comme garde. C'est là que j'allais, finalement.