C++ Access an element of pair inside vector
Asked Answered
F

4

7

I have a vector with each element being a pair. I am confused with the syntax. Can someone please tell me how to iterate over each vector and in turn each element of pair to access the class.

    std::vector<std::pair<MyClass *, MyClass *>> VectorOfPairs;

Also, please note, I will be passing the values in between the function, hence VectorOfPairs with be passed by pointer that is *VectorOfPairs in some places of my code.

Appreciate your help. Thanks

Frontlet answered 8/10, 2012 at 16:1 Comment(0)
C
10

Here is a sample. Note I'm using a typedef to alias that long, ugly typename:

typedef std::vector<std::pair<MyClass*, MyClass*> > MyClassPairs;

for( MyClassPairs::iterator it = VectorOfPairs.begin(); it != VectorOfPairs.end(); ++it )
{
  MyClass* p_a = it->first;
  MyClass* p_b = it->second;
}
Clamp answered 8/10, 2012 at 16:4 Comment(0)
M
11

This should work (assuming you have a C++11 compatible compiler)

for ( auto it = VectorOfPairs.begin(); it != VectorOfPairs.end(); it++ )
{
   // To get hold of the class pointers:
   auto pClass1 = it->first;
   auto pClass2 = it->second;
}

If you don't have auto you'll have to use std::vector<std::pair<MyClass *, MyClass *>>::iterator instead.

Metamathematics answered 8/10, 2012 at 16:4 Comment(4)
Personally not a fan of auto. No downvote tho, good answer.Clamp
@JohnDibling It's great for iterators, it's also mandatory for certain types of template patterns.Metamathematics
I understand the reasons why auto was added to the language. I'm fine with using it when you have to. I just think using auto when it's not needed is a bit lazy, and could contribute to a generation of programmers that don't really know what they are doing. I suspect I'm pretty on my own with this opinion, however.Clamp
@JohnDibling I think that'd be a valid concern if it wasn't strongly typed. However, you have to know what it really is in order to pass it into a function (for example) so I don't think the knowledge required is any less. It just tidies up otherwise ugly/lengthy declarations.Metamathematics
C
10

Here is a sample. Note I'm using a typedef to alias that long, ugly typename:

typedef std::vector<std::pair<MyClass*, MyClass*> > MyClassPairs;

for( MyClassPairs::iterator it = VectorOfPairs.begin(); it != VectorOfPairs.end(); ++it )
{
  MyClass* p_a = it->first;
  MyClass* p_b = it->second;
}
Clamp answered 8/10, 2012 at 16:4 Comment(0)
G
5

Yet another option if you have a C++11 compliant compiler is using range based for loops

for( auto const& v : VectorOfPairs ) {
  // v is a reference to a vector element
  v.first->foo();
  v.second->bar();
}
Galligan answered 8/10, 2012 at 16:8 Comment(1)
+1: I wish my C++11 "compliant" major-vendor compiler supported range-based for loops. :(Clamp
B
1

You can access the elements of pairs inside vector in C++17 in a following style by combining range-based for loop and structured bindings. Example:

for (auto& [x, y] : pts) {
    cin >> x >> y;
}

where pts is a vector of pairs. & is used to make formal "uniquely-named variable" e of structured binding a reference so that x and y referring to subobjects of e refer to original pair inside pts, which can be modified this way (e.g. cin can be used to input to it). Without &, e would be a copy (to subobjects of which x and y again refer). Example using your VectorOfPairs:

for (auto [pFirst, pSecond] : VectorOfPairs ) {
    // ...
}

Also you can make e a reference to const when modification through structured binding is not needed and you want to avoid potentially expensive copy of a pair (though this should not be a problem in your case since pair object consisting of 2 pointers is pretty small and cheap to copy). Example:

for (const auto& [pFirst, pSecond] : VectorOfPairs ) {
    // ...
}
Burd answered 16/7, 2022 at 5:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.