C++17: Yes! You should use a structured binding declaration. The syntax has been supported in gcc and clang for years (since gcc-7 and clang-4.0) (clang live example). This allows us to unpack a tuple like so:

for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) { // ... }

The above will give you:

int i set to 1

set to double f set to 1.0

set to std::string s set to "ab"

Make sure to #include <tuple> for this kind of declaration.

You can specify the exact types inside the tuple by typing them all out as I have with the std::string , if you want to name a type. For example:

auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}

A specific application of this is iterating over a map, getting the key and value,

std::unordered_map<K, V> m = { /*...*/ }; for (auto& [key, value] : m) { // ... }

See a live example here

C++14: You can do the same as C++11 (below) with the addition of type-based std::get . So instead of std::get<0>(t) in the below example, you can have std::get<int>(t) .

C++11: std::make_pair allows you to do this, as well as std::make_tuple for more than two objects.

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 will return the two arguments in a std::pair . The elements can be accessed with .first and .second .

For more than two objects, you'll need to use 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 is a variadic template that will construct a tuple of any number of arguments (with some technical limitations of course). The elements can be accessed by index with std::get<INDEX>(tuple_object)

Within the for loop bodies you can easily alias the objects, though you still need to use .first or std::get for the for loop condition and update expression

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 and C++03 You can explicitly name the types of a std::pair . There is no standard way to generalize this to more than two types though: