Alina
Alina

Reputation: 21

How can i avoid the use of the auto specifier in range-based for loops?

I am trying to use the auto specifier in the next loop

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]));
    }
}

where graf is a vector of pairs, and it seems not to work in c++98, and i do not know how to turn it into a more usual kind of loop. Is there any way to avoid it ?

Upvotes: 0

Views: 164

Answers (2)

Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29975

Range for is not magic. It has a definition:

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

Means

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

auto isn't magic either. It is just a placeholder for the actual type.

Having said that, you can use cppinsights.io to translate some of the shortcuts in modern C++ to more traditional concepts. For instance. This:

#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 is an implementation detail, but besides that it's very clear what is going on.

Upvotes: 0

Jarod42
Jarod42

Reputation: 217275

You might turn C++11

for (auto x : graf[nod])

into C++03

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

Upvotes: 3

Related Questions