How to iterate std::set?
You must dereference the iterator in order to retrieve the member of your set.
std::set<unsigned long>::iterator it;
for (it = SERVER_IPS.begin(); it != SERVER_IPS.end(); ++it) {
u_long f = *it; // Note the "*" here
}
If you have C++11 features, you can use a range-based for loop:
for(auto f : SERVER_IPS) {
// use f here
}
How to iterate through all elements of set C++
addStudent
takes a pointer, while it
is an iterator, so can't be passed directly.
You should change addStudent
to take either a value or a pointer/reference to const
:
// option 1
void addStudent(Student);
addStudent(*it);
// option 2
void addStudent(Student const &);
addStudent(*it);
// option 3
void addStudent(Student const *);
addStudent(&*it);
If, as you say in a comment, you must leave it taking a mutable pointer, then you'll need some grotesquery to deal with the fact that elements of the set are immutable:
// nasty option
addStudent(const_cast<Student*>(&*it));
// slightly less nasty option
Student copy = *it;
addStudent(©);
Beware that the first option will give undefined behaviour if the function uses the dodgy pointer to make any modification to the Student
object stored in the set. The second makes a temporary copy, which can be modified without breaking the set. This is fine as long as addStudent
only stores a copy of the object passed to it, not the pointer itself, which will become invalid when copy
is destroyed.
How to iterate over a specific range of std::set/std::multiset?
You cannot do set.begin()+a
, but you can do std::advance(it, a)
:
#include <iostream>
#include <set>
#include <string>
int main()
{
std::set<std::string> set={ "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
size_t a = 1, b = 4;
auto it = set.begin(), it_end = set.begin();
std::advance(it, a);
std::advance(it_end, b);
for(; it!= it_end; ++it)
std::cout << *it << " ";
}
Unfortunately you cannot do something like auto it = std::advance(set.begin(), a);
, because advance
gets the iterator by reference and changes it inplace.
https://ideone.com/8nRjgr
Better solution use std::next
, thanks to @Evg:
#include <iostream>
#include <set>
#include <string>
int main()
{
std::set<std::string> set={ "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
size_t a = 1, b = 4;
for(auto it = std::next(set.begin(), a), it_end = std::next(it, b-a); it != it_end; ++it)
std::cout << *it << " ";
}
https://ideone.com/6wgpMZ
How to iterate std::set based on offset from set.begin()?
I need to get to the iterator having offset
ofst
:it + ofst
: is there
a way to do that?
No, there is no operator+
overload defined for this for std::set::iterator
(aka bidirectional iterators). However, you can use std::next
, from <iterator>
header as follows to achive the same.
#include <iterator> // std::next
auto nthIter = std::next(it, ofst);
This basically behind the scene increments ofst
times too.
The std::set
has bidirectional iterators, which has no luxuries like random access iterators, and hence need to increment like this.
That being said, you could overload the operator+
(and maybe operator-
) for the bidirectional iterators, which will not be recommended though.
std::set iterating over all pairs
it1 + 1
is a random access operation, so it requires the iterator to be a random access iterator, and since std::set<int>::iterator
is not a random access iterator, it does not support this operation.
++it2
requires that the iterator is a forward iterator, and since std::set<int>::iterator
is a bidirectional iterator, it is a forward iterator.
How iterating over a std::set returns sorted results
We can find a definitive answer by looking at the source code (libstdc++ 5.2.1 in this case). This is how a tree node looks like:
// <libstdc++>/include/bits/stl_tree.h
struct _Rb_tree_node_base {
typedef _Rb_tree_node_base* _Base_ptr;
_Rb_tree_color _M_color;
_Base_ptr _M_parent;
_Base_ptr _M_left;
_Base_ptr _M_right;
// ...
}
So every node contains a color, and pointers to its parent and its left and right children. Incrementing is implemented as:
// <libstdc++>/include/bits/stl_tree.h
struct _Rb_tree_iterator {
_Self& operator++() {
_M_node = _Rb_tree_increment(_M_node);
return *this;
}
// ...
private:
_Base_ptr _M_node;
};
The actual increment is not in the public headers anymore, but in the compiled part of the library:
// <libstdc++>/src/c++98/tree.cc
static _Rb_tree_node_base* local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
{
if (__x->_M_right != 0) {
__x = __x->_M_right;
while (__x->_M_left != 0)
__x = __x->_M_left;
} else {
_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_right) {
__x = __y;
__y = __y->_M_parent;
}
if (__x->_M_right != __y)
__x = __y;
}
return __x;
}
So, ultimately, it's a textbook implementation of tree traversal: The iterator holds a pointer to the "current" node, and to get to the next node it goes up in the tree as long as it was coming from the right child. If it was coming from the left child, it will descend to leftmost child node of the right child.
how to iterate through a set of sets C++
I would do it this way:
// Iterate through and print output
set < set <string> >::iterator it_ex; // iterator for the "outer" structure
set <string>::iterator it_in; // iterator for the "inner" structure
for(it_ex = Triplets.begin(); it_ex != Triplets.end(); it_ex++)
{
for(it_in = it_ex->begin(); it_in != it_ex->end(); it_in++)
cout << *it_in << ", ";
cout << endl;
}
Why is iterating over a std::set so much slower than over a std::vector?
Isn't a set just a structured vector that checks whether each item is unique upon insertion?
No, by far not. These data structures are completely different, and the main distinction here is the memory layout: std::vector
puts its element into a contiguous location in memory, while std::set
is a node-based container, where every element is separately allocated and resides at distinct places in memory, possibly far away from each other and definitely in a way that pre-fetching data for fast traversal is impossible for the processor. This is quite the opposite for std::vector
- as the next element is always just right "next to" the current one in memory, a CPU will load elements into its cache, and when actually processing the elements, it only has to go to the cache to retrieve the values - which is very fast compared to RAM access.
Note that it's a common need to have a sorted, unique collection of data that is laid out contiguously in memory, and C++2a or the version thereafter might actually ship with a flat_set
, have a look at P1222.
Matt Austern's "Why you shouldn't use set (and what you should use instead)" is an interesting read, too.
How to iterate through a STL set till the second last element?
You may use the following in C++11:
std::set<std::bitset<2501>> arr;
std::set<std::bitset<2501>>::iterator end= arr.end();
for(std::set<std::bitset<2501> >::iterator it1 = arr.begin();it1 != end; ++it1)
{
for(std::set<std::bitset<2501> >::iterator it2 = std::next(it1); it2 != end; ++it2)
{
//do processing, I didn't show the OR operation
}
}
Related Topics
Visual C++ 2008 Express Download Link Dead
The New Keyword "Auto"; When Should It Be Used to Declare a Variable Type
What Exactly Is Streambuf? How to Use It
Easy Rule to Read Complicated Const Declarations
How to Convert from Int to Char*
Why Do We Require Requires Requires
C++11 Member Initializer List VS In-Class Initializer
Returning a Const Reference to an Object Instead of a Copy
Why Would I Prefer Using Vector to Deque
How to Implement a BéZier Curve in C++
How to Enable Core Dump in My Linux C++ Program
Why Should I Ever Use Inline Code
How to See the Template Instantiated Code by C++ Compiler
Why Does a C/C++ Compiler Need Know the Size of an Array at Compile Time
What Is a Constant Reference? (Not a Reference to a Constant)
Linking with Clang++ on Os X Generates Lots of Symbol Not Found Errors
Visual Studio 2015 Run-Time Dependencies or How to Get Rid of Universal Crt