【问题标题】:How can i avoid the use of the auto specifier in range-based for loops?如何避免在基于范围的 for 循环中使用 auto 说明符?
【发布时间】:2020-03-04 11:28:00
【问题描述】:

我正在尝试在下一个循环中使用自动说明符

for (auto x : graf[nod])
{
    if (cost + x.second < dist[x.first])
    {
        dist[x.first] = cost+x.second;
        pq.push(make_pair(x.first, dist[x.first]));
    }
}

其中 graf 是对的向量,它似乎在 c++98 中不起作用,我不知道如何将它变成一种更常见的循环。有什么办法可以避免吗?

【问题讨论】:

标签: c++ for-loop auto c++03


【解决方案1】:

你可能会转向 C++11

for (auto x : graf[nod])

进入 C++03

for (std::size_t i = 0; i != graf[nod].size(); ++i) {
    std::pair<T1, T2> x = graf[nod][i];
    // ...
}

【讨论】:

  • 确实,std::vector 是微不足道的。
  • 这是正确的答案,但它有意义吗?要访问向量中的一对,它应该只是 for (auto x : graf)?
  • @anastaciu - 确实有道理,因为问题是关于 C++ 11 之前的 C++ 版本 - 这是引入基于范围的 for 和 auto 类型推导的标准.
  • @Peter,是的,答案很完美,我怀疑 OP 对数据的访问。
  • @Peter:我认为 anastciu 的疑问是关于 OP 描述(“graf 是对的向量”)和代码 graf[node] 作为容器的不匹配。 (而且我倾向于使用代码作为最新文档)
【解决方案2】:

范围不是魔术。它有一个definition

for ( init-statement(optional)range_declaration : range_expression ) loop_statement

意思

{
  init - statement 
  auto&& __range = range_expression;
  auto __begin = begin_expr;
  auto __end = end_expr;
  for (; __begin != __end; ++__begin) {
    range_declaration = *__begin;
    loop_statement
  }
}

auto 也不是魔法。它只是实际类型的占位符。

话虽如此,您可以使用cppinsights.io 将现代 C++ 中的一些快捷方式转换为更传统的概念。例如。这个:

#include <utility>
#include <vector>

int main() {
  std::vector<std::vector<std::pair<int, int>>> graf;

  // fill graf

  for (auto x : graf[0]) {
    x.first += x.second;
  }
}

Translates to:

#include <utility>
#include <vector>

int main()
{
  std::vector<std::vector<std::pair<int, int> > > graf = std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > >();
  {
    std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > & __range1 = graf.operator[](0);
    std::__wrap_iter<std::pair<int, int> *> __begin1 = __range1.begin();
    std::__wrap_iter<std::pair<int, int> *> __end1 = __range1.end();
    for(; std::operator!=(__begin1, __end1); __begin1.operator++()) 
    {
      std::pair<int, int> x = std::pair<int, int>(__begin1.operator*());
      x.first += x.second;
    }

  }
}

std::__wrap_iter 是一个实现细节,但除此之外,发生了什么非常清楚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 2013-06-06
    • 2016-10-31
    • 2011-10-21
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多