C ++ 17 : Sì! È necessario utilizzare una dichiarazione di associazione strutturata . La sintassi è supportata in gcc e clang da anni (dal momento che gcc-7 e clang-4.0) ( esempio live di clang ). Questo ci consente di decomprimere una tupla in questo modo:
for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
// ...
}
Quanto sopra ti darà:
int i
impostato 1
double f
impostato 1.0
std::string s
impostato "ab"
Assicurati di #include <tuple>
questo tipo di dichiarazione.
Puoi specificare i tipi esatti all'interno tuple
di digitandoli tutti come ho fatto con il std::string
, se vuoi nominare un tipo. Per esempio:
auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}
Un'applicazione specifica di questo sta iterando su una mappa, ottenendo la chiave e il valore,
std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
// ...
}
Guarda un esempio dal vivo qui
C ++ 14 : puoi fare lo stesso di C ++ 11 (sotto) con l'aggiunta di tipo-based std::get
. Quindi, invece che std::get<0>(t)
nell'esempio seguente, puoi avere std::get<int>(t)
.
C ++ 11 : std::make_pair
consente di farlo, oltre che std::make_tuple
per più di due oggetti.
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
restituirà i due argomenti in a std::pair
. È possibile accedere agli elementi con .first
e .second
.
Per più di due oggetti, dovrai usare a 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
è un modello variadico che costruirà una tupla di qualsiasi numero di argomenti (con alcune limitazioni tecniche ovviamente). È possibile accedere agli elementi tramite indice constd::get<INDEX>(tuple_object)
All'interno dei corpi del ciclo for è possibile facilmente alias degli oggetti, sebbene sia ancora necessario utilizzare .first
o std::get
per la condizione del ciclo for e l'espressione di aggiornamento
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 e C ++ 03 È possibile assegnare un nome esplicito ai tipi di a std::pair
. Non esiste un modo standard per generalizzare questo in più di due tipi:
for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
-std=c++0x
) sotto forma difor(auto i=0, j=0.0; ...
, ma questa possibilità è stata rimossa in g ++ - 4.5 in coincidenza con i testi c ++ 0x.