是否可以在 for 循环中声明两个不同类型的变量?

新手上路,请多包涵

是否可以在 C++ 的 for 循环的初始化体中声明两个不同类型的变量?

例如:

 for(int i=0,j=0 ...

定义两个整数。我可以在初始化正文中定义一个 int 和一个 char 吗?这将如何完成?

原文由 Nathan Osman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

C++17是的! 您应该使用 结构化绑定声明。自 gcc-7 和 clang-4.0 ( clang live example ) 以来,gcc 和 clang 就支持该语法。这允许我们像这样解包一个元组:

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

以上将为您提供:

  • int i 设置为 1
  • double f 设置为 1.0
  • std::string s 设置为 "ab"

确保 #include <tuple> 进行此类声明。

如果你想命名一个类型,你可以指定 tuple 中的确切类型,就像我用 std::string 一样全部输入。例如:

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

一个具体的应用是遍历一个映射,获取键和值,

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

在此处 查看实时示例


C++14 :您可以与 C++11(如下)相同,添加基于类型的 std::get 。因此,在下面的示例中,您可以使用 --- 代替 std::get<0>(t) std::get<int>(t)


C++11 : std::make_pair 允许你这样做,以及 std::make_tuple 用于两个以上的对象。

 for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
    std::cout << p.second << '\n';
}

std::make_pair 将返回 std::pair 中的两个参数。可以使用 .first.second 访问这些元素。

对于两个以上的对象,您需要使用 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) << '\n'; // cout Hello world
    std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}

std::make_tuple 是一个可变参数模板,它将构造一个包含任意数量参数的元组(当然有一些技术限制)。元素可以通过索引访问 std::get<INDEX>(tuple_object)

在 for 循环体中,您可以轻松地为对象设置别名,尽管您仍然需要使用 .firststd::get 用于 for 循环条件和更新表达式

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 << '\n'; // cout Hello world
    v.push_back(i); // add counter value to the vector
}


C++98 和 C++03 您可以显式命名 std::pair 的类型。但是,没有标准的方法可以将其推广到两种以上的类型:

 for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
    std::cout << p.second << '\n';
}

原文由 Ryan Haining 发布,翻译遵循 CC BY-SA 4.0 许可协议

有关嵌套多个 for 循环的另一种方法,请参阅“ 有没有办法在 for 循环中定义两种类型的变量? ”。与 Georg 的“结构技巧”相比,另一种方式的优势在于它 (1) 允许您混合使用静态和非静态局部变量,以及 (2) 它允许您拥有不可复制的变量。缺点是它的可读性要差得多,而且效率可能较低。

原文由 tgoodhart 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题