C ++ 17 : Sim! Você deve usar uma declaração de ligação estruturada . A sintaxe é suportada no gcc e no clang há anos (desde gcc-7 e clang-4.0) ( exemplo ao vivo do clang ). Isso nos permite descompactar uma tupla assim:
for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
// ...
}
O exposto acima lhe dará:
int i
definido como 1
double f
definido como 1.0
std::string s
definido como "ab"
Certifique-se de #include <tuple>
que este tipo de declaração.
Você pode especificar os tipos exatos dentro do tuple
, digitando todos eles como eu fiz com o std::string
, se desejar nomear um tipo. Por exemplo:
auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}
Uma aplicação específica disso está iterando sobre um mapa, obtendo a chave e o valor,
std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
// ...
}
Veja um exemplo ao vivo aqui
C ++ 14 : você pode fazer o mesmo que o C ++ 11 (abaixo) com a adição de tipos std::get
. Então, em vez de std::get<0>(t)
no exemplo abaixo, você pode ter std::get<int>(t)
.
C ++ 11 : std::make_pair
permite fazer isso, além std::make_tuple
de mais de dois objetos.
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
retornará os dois argumentos em a std::pair
. Os elementos podem ser acessados com .first
e .second
.
Para mais de dois objetos, você precisará usar um 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
é um modelo variável que construirá uma tupla de qualquer número de argumentos (com algumas limitações técnicas, é claro). Os elementos podem ser acessados por índice comstd::get<INDEX>(tuple_object)
Dentro dos corpos do loop for, você pode facilmente alias os objetos, embora ainda precise usar .first
ou std::get
para a condição do loop for e atualizar a expressão
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 Você pode nomear explicitamente os tipos de a std::pair
. Porém, não há uma maneira padrão de generalizar isso para mais de dois tipos:
for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
-std=c++0x
) na forma defor(auto i=0, j=0.0; ...
, mas essa possibilidade foi removida em g ++ - 4.5 para coincidir com os textos c ++ 0x.