C ++ 17 : Oui! Vous devez utiliser une déclaration contraignante structurée . La syntaxe est prise en charge dans gcc et clang depuis des années (depuis gcc-7 et clang-4.0) ( exemple live clang ). Cela nous permet de décompresser un tuple comme ceci:
for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
// ...
}
Ce qui précède vous donnera:
int i
mis à 1
double f
mis à 1.0
std::string s
mis à "ab"
Assurez-vous de #include <tuple>
ce type de déclaration.
Vous pouvez spécifier les types exacts à l'intérieur du tuple
en les tapant tous comme je l'ai fait avec le std::string
, si vous voulez nommer un type. Par exemple:
auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}
Une application spécifique de cela est l'itération sur une carte, l'obtention de la clé et de la valeur,
std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
// ...
}
Voir un exemple en direct ici
C ++ 14 : vous pouvez faire la même chose que C ++ 11 (ci-dessous) avec l'ajout de type std::get
. Donc, au lieu de std::get<0>(t)
dans l'exemple ci-dessous, vous pouvez avoir std::get<int>(t)
.
C ++ 11 : std::make_pair
vous permet de le faire, ainsi que std::make_tuple
pour plus de deux objets.
for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
std::make_pair
renverra les deux arguments dans un std::pair
. Les éléments sont accessibles avec .first
et .second
.
Pour plus de deux objets, vous devrez utiliser un std::tuple
for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
std::get<0>(t) < 10;
++std::get<0>(t)) {
std::cout << std::get<1>(t) << std::endl; // cout Hello world
std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}
std::make_tuple
est un modèle variadique qui va construire un tuple de n'importe quel nombre d'arguments (avec quelques limitations techniques bien sûr). Les éléments sont accessibles par index avecstd::get<INDEX>(tuple_object)
Dans les corps de boucle for, vous pouvez facilement aliaser les objets, même si vous devez toujours utiliser .first
ou std::get
pour la condition de boucle for et l'expression de mise à jour
for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
std::get<0>(t) < 10;
++std::get<0>(t)) {
auto& i = std::get<0>(t);
auto& s = std::get<1>(t);
auto& v = std::get<2>(t);
std::cout << s << std::endl; // cout Hello world
v.push_back(i); // add counter value to the vector
}
C ++ 98 et C ++ 03 Vous pouvez nommer explicitement les types de a std::pair
. Il n'y a pas de moyen standard de généraliser cela à plus de deux types:
for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
-std=c++0x
) sous la forme defor(auto i=0, j=0.0; ...
, mais cette possibilité a été supprimée dans g ++ - 4.5 pour coïncider avec les textes c ++ 0x.