-2

I have a vector:

std::vector<std::pair<int, long> > v;
v.push_back(std::make_pair(1, 2L));
etc...

How can I iterate through it and get out the int and the long elements from it?

beans
  • 1,765
  • 5
  • 25
  • 31
  • 2
    Have you tried anything? That failing, have you tried iterating a more simple vector and extracting the values from a pair separately, and then combining the two techniques? – chris Dec 01 '12 at 16:28
  • Would this be helpfull? http://stackoverflow.com/questions/409348/iteration-over-vector-in-c – Kat Dec 01 '12 at 16:29

2 Answers2

5

Using C++03:

for (std::vector<std::pair<int, long> >::iterator i = v.begin(); i != v.end(); ++i)
{
    std::cout << "int: " << i->first << " long: " << i->second << std::endl;
}

Using C++11:

for (std::pair<int, long> p : v) // could also do auto p, auto& p, or (const) std::pair<int, long>& p
{
    std::cout << "int: " << p.first << " long: " << p.second << std::endl;
}
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • 3
    In C++11, I'd probably use `auto` and save a bit of typing, to be honest. – chris Dec 01 '12 at 16:30
  • @chris: That's true. I just wanted to show beans what the types were. But yes, using `auto` would help things be more concise. I added a comment – Cornstalks Dec 01 '12 at 16:30
  • Does not work... no match for 'operator!=' in 'i != ((News*)this)->News::v.std::vector<_Ty, _Ax>::end [with _Ty = std::pair, _Ax = std::allocator >, std::vector<_Ty, _Ax>::iterator = std::_Vector_iterator, std::allocator > >, typename std::_Vector_val<_Ty, _Ax>::_Alty = std::allocator >]()' – beans Dec 01 '12 at 16:40
  • @Cornstalks: The second one creates a copy of each pair, you should use a reference instead. `auto p` would still make a copy, `auto &p` wouldn't. – Thibaut Dec 01 '12 at 16:57
  • @beans: [Works for me](http://ideone.com/O7xWvb). But I see you're using `QString` and not `long`. I don't know what else is different in your code. – Cornstalks Dec 01 '12 at 16:58
  • @Thibaut: I've got a comment about using `(const) std::pair& p`, but I'll also add one for `auto& p`. Thanks for catching that. – Cornstalks Dec 01 '12 at 16:59
0

The short answer is: "by strong preference, with an algorithm". The real question is what you're going to do with the items. To use @cornstalks' example, if you want to print them out, you could do something like this:

typedef std::pair<int, long> v_t;

std::vector<v_t> v;

std::ostream &operator<<(std::ostream &os, v_t const &p) { 
    return os << p.first << "\t" << p.second;
}

std::copy(v.begin(), v.end(), std::ostream_iterator<v_t>(std::cout, "\n"));

Let's try something else. Maybe you want to add the items together -- i.e., get a pair<int, long> in which each item is the sum of the corresponding items from the array:

std::accumulate(v.begin(), v.end(), std::make_pair(0,0L), 
               [](v_t const &a, v_t const &b) { 
                    return std::make_pair(a.first+b.first, a.second+b.second); 
               });

Note that in this case, I'm assuming a (reasonably) recent C++ compiler. The [](params){statement;} part is a "lambda" -- basically an in-place definition of a function object. It was officially added to C++ in the 2011 standard, but was known about enough before 2011 that most compilers since around 2009 implement them (e.g., Visual Studio 2010 and gcc going back to at least 4.7 both do).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111