Convert the end() iterator to a pointer - c++

To get to the point: is the following safe ?
vector<int> v;
int const* last = &*v.end();
// last is never dereferenced
My concern is that the trick to get a plain old pointer from an iterator forces to dereference the end() iterator, which is not valid... even if it is just to take the pointer back!
Backgroud: I am trying to create a collection of entries indexed by arbitrary types (especially integers and pointer to objects).
template<class IT>
/// requires IT implements addition (e.g. int, random-access iterator)
class IndexingFamily {
public:
using IndexType = IT;
IndexingFamily(IndexType first, IndexType last);
int size() const;
IndexType operator[](int i) const;
private:
IndexType first;
IndexType last;
};
template<class IT> IndexingFamily<IT>::
IndexingFamily(IndexType first, IndexType last)
: first(first)
, last(last) {}
template<class IT> auto IndexingFamily<IT>::
size() const -> int {
return last-first;
}
template<class IT> auto IndexingFamily<IT>::
operator[](int i) const -> IndexType {
return first+i;
}
template<class IT, class ET>
struct IndexedEntry {
using IndexType = IT;
using EntryType = ET;
IndexType index;
EntryType entry;
};
template<class IT, class ET>
class CollectionOfEntries {
public:
using IndexType = IT;
using EntryType = ET;
/// useful methods
private:
IndexingFamilyType indexingFamily;
vector<EntryType> entries;
};
struct MyArbitraryType {};
int main() {
MyArbitraryType obj0, obj1, obj2;
vector<MyArbitraryType> v = {obj0,obj1,obj2};
using IndexType = MyArbitraryType const*;
IndexingFamily<IndexType> indexingFamily(&*v.begin(),&*v.end());
using EntryType = double;
using IndexedEntryType = IndexedEntry<IndexType,EntryType>;
IndexedEntry entry0 = {&obj0,42.};
IndexedEntry entry1 = {&obj1,43.};
vector<IndexedEntryType> entries = {entry0,entry1};
CollectionOfEntries coll = {indexingFamily,entries};
return 0;
}

Dereferencing an end() iterator gives undefined behaviour, with any standard container.
For a vector you can get a pointer corresponding to the end() iterator using
pointer_to_end = v.empty() ? 0 : (&(*v.begin()) + v.size());
or
pointer_to_end = v.data() + v.size(); // v.data() gives null is size is zero
The check of v.empty() is needed since, if v is empty, v.begin() == v.end(). For C++11 or later, use of nullptr instead of 0 in the above is often considered preferable.

The iterator returned by member function end() "points" after the last element of a vector. You may not dereference it. Otherwise the program will have undefined behavior.
You can get the corresponding pointer the following way
vector<int> v;
int const *last = v.data() + v.size();
If you want to use the iterator returned by the member function end() you can write
vector<int> v;
int const *last = v.data() + std::distance( v.begin(), v.end() );
Take into account that member function data() returns a raw pointer of the memory extent occupied by vector's data.

Related

reference with const access

Using pointers, I can create all combinations of (const/non_const) to (T / const T) for any type T, as discussed in detail this answer.
But using references, how can I define a reference to a variable which can be dereferences (like an iterator), such that the dereferenced reference gives a const access?
For example, consider this program:
#include <array>
int main()
{
std::array<int, 3> a{0, 0, 0};
auto const& iter = a.begin();
// iter++; // Error!
(*iter)++;
}
iter is const variable, and if you uncomment the line iter++ the code cannot compile.
But iter dereferences to a non-const int, which in fact can be incremented with (*iter)++. In a sense, iter mimics int * const, i.e., a const pointer to int.
Is it possible to instead have a (const or non_const) reference iter, such that *iter is a const int?
Please bear in mind that I am aware that I could use const auto& iter = a.cbegin() in the example above. The purpose of the question is how to define iter, such that, when dereferenced, give a const access, irrespective of what is on the right of the equal operator.
For iterators I can imagine to explicitly bind to a const_iterator, like:
const decltype(a)::const_iterator& iter = a.begin();
This solution works because I know that the equivalent "const-access" of an iterator is a const_iterator.
But, more generally:
(some type)& iter = rhs
If all I know is that *rhs is a int, is it possible to find out the type of iter, such that *iter is a const int?
Another point worth to consider is the possible cost of the conversion of rhs.
Is it possible to instead have a (const or non-const) reference iter, such that *iter is a const int?
You call the std::array::cbegin() member function that will return a std::array<int, 3>::const_iterator. Dereferencing that will give you a const int&.
You can however not take the const_iterator by a non-const reference. You must take it by value or by const& (to prolong the life of the temporary returned by the cbegin() function). The general recommendation is to take iterators by value though.
is it possible to find out the type of iter, such that *iter is a const int?
If you know that iter is some kind of pointer (const T*, const T*&, T* or T*& etc.) then you could get a const T* like this:
const std::remove_cvref_t<decltype(iter)> constiter = iter;
For the general case, getting a const_iterator from an iterator without using the container's typedef for const_iterator, will be a bit cumbersome. One way could be to wrap the iterator in an interator class that only returns const&s when dereferenced.
Here's an example with a std::list<int>::iterator which is a little more complicated than a pointer. It works for pointers too though.
#include <iostream>
#include <list>
template<class It>
struct const_iterator {
using IterType = std::remove_reference_t<It>;
using Traits = std::iterator_traits<IterType>;
using difference_type = typename Traits::difference_type;
using value_type = const typename Traits::value_type;
// ^^^^^
using pointer = value_type*;
using reference = value_type&;
using iterator_category = typename Traits::iterator_category;
const_iterator(It nc) : value(nc) {}
// dereferencing gives a const&
reference operator*() const { return *value; }
bool operator==(const const_iterator& rhs) const { return value == rhs.value; }
bool operator!=(const const_iterator& rhs) const { return !(*this == rhs); }
const_iterator& operator++() { ++value; return *this; }
const_iterator operator++(int) { const_iterator rv(*this); ++value; return rv; }
// Add conditional support for proxy member functions supported
// by the original iterator type / iterator_category
IterType value;
};
template<class It>
const_iterator(It) -> const_iterator<It>;
int main()
{
std::list<int> a{1, 2, 3};
auto iter = a.begin();
*iter = 10; // Ok
const_iterator cit(iter); // make a const_iterator from the original iterator
++cit; // Ok
std::cout << *cit << '\n'; // prints 2
//*cit = 20; // Error: *cit is a `const int&`
}
The purpose of the question is how to define iter, such that, when dereferenced, give a const access
And this is where const iterators come into play. For iterators it's actually a less global question, because a const iterator merely means a standard iterator to a constant container:
const std::array<int, 3> a{ 0, 0, 0 };
static_assert(
std::is_same_v<decltype(a.begin()), decltype(a.cbegin())>,
"The iterators are of different type"
);
Constness of the iterators' own types in this case doesn't actually depend on whether they point to a const type or not. As you already noticed, const iterator instead means that the iterator itself cannot be changed and point to a different object.
Answering your second question:
Is it possible to instead have a (const or non_const) reference to const int?
No, a reference is always const implicitly and cannot be rebound after being bound to a variable.

C++ Filteration using lazy iterator

template<typename Iterator>
struct Range {
using LazyIterator = Iterator; // required for accessing the used Iterator type from other locations
Iterator m_begin;
Iterator m_end;
auto begin() { return m_begin; }
auto end() { return m_end; }
};
template<typename Iterator>
Range(Iterator, Iterator) -> Range<Iterator>;
template<typename Iterator, typename Callable>
struct FilteringIterator : Iterator {
Callable callable;
using OriginalIterator = Iterator;
using t = typename OriginalIterator::value_type;
FilteringIterator(const Iterator begin, Callable callable):Iterator(begin),callable(callable){}
Iterator &get_orig_iter() { return ((Iterator &)*this); }
auto operator*() { return callable(*get_orig_iter()); }
};
auto filter = [](auto action) {
return [=]( auto &container) {
using Container = std::decay_t<decltype(container)>;
using Iterator = typename Container::iterator;
using actiontype = decltype(action);
using filter_iterator = FilteringIterator<Iterator, actiontype>;
return Range{filter_iterator{container.begin(),action}, filter_iterator{container.end(),action}};
};
};
I need a lazy iterator that will traverse over a range and filter it lazily.
For example
auto v = std::vector<double>{};
auto odd_gen = views::odds();
for(int i=0; i<5; ++i)
v.push_back(odd_gen() * 2.5);
// v contains {2.5, 7.5, 12.5, 17.5, 22.5} here
new_line();
for(auto a : v | filter(greater_than(15))) // filter is applied lazily as the range is traversed
std::cout << a << std::endl;
// print { 17.5, 22.5} here
but it prints
{0,0,0,0,17.5,22.5}
I want it to only print 17.5, 22.5
how can I achieve that?
Your code never skips elements, it just transforms them. You need to make sure that when the operator*() is invoked, it starts by advancing the iterator while callable returns false, and only then return the value pointed to by the Iterator.
There are corner cases though you have to take care of. If the input ends with elements that don't match the filter, then you run into a problem. You also need to skip over all filtered out elements when operator++() is called. And also think about the case where the filter would not match any elements of the input; in that case you must ensure that begin() is equal to end().

Transform an iterator on an unordered_map with pointer value type to an iterator on the same map with const reference value type

I have the following class :
#include <unordered_map>
#include <memory>
class Node {
public:
typedef std::unique_ptr<Node> ptr_type;
typedef std::unordered_map<char, ptr_type> map_type;
typedef /**???**/ const_iterator;
const_iterator begin() const;
const_iterator end() const;
private:
map_type _children;
};
As you can see, I want a way fo a user of this class to iterate over elements of _children without being able to modify them. That is why I want to create an iterator that point to elements of type pair<char, const Node&> instead of pair<char, ptr_type>.
Creating a base iterator class seems a little too complicated for the task at hand. I have taken a look at boost iterator, I think transform_iterator may be the way to go, but I have not yet found how to make it work.
While I'm at it, does anyone know where I can find examples of the different examples of iterators defined in boost-iterators ? There is only one example in the doc for each type, and they do not always fit my needs (I'm new to this library, I may have missed something obvious).
UPDATE: Here is my attempt at using boost::transform_iterator
class Node {
public:
typedef std::unique_ptr<Node> ptr_type;
typedef std::unordered_map<char, ptr_type> map_type;
struct Transformer {
std::pair<char, const Node&> operator()(const std::pair<char, ptr_type> &p) const {
return std::pair<char, const Node&>(p.first, *p.second);
}
};
typedef boost::transform_iterator<Transformer, map_type::const_iterator, std::pair<char, const Node&>&, std::pair<char, const Node&>> const_iterator;
const_iterator begin() const {
return boost::make_transform_iterator<Transformer, map_type::const_iterator>(_children.begin(), Transformer());
}
const_iterator end() const {
return boost::make_transform_iterator<Transformer, map_type::const_iterator>(_children.end(), Transformer());
}
private:
map_type _children;
};
It unfortunately does not compile, and gives the following error:
error: no type named ‘type’ in ‘boost::mpl::eval_if<boost::is_same<boost::iterators::use_default, boost::iterators::use_default>, boost::result_of<const Node::Transformer(const std::pair<const char, std::unique_ptr<Node> >&)>, boost::mpl::identity<boost::iterators::use_default> >::f_ {aka struct boost::result_of<const Node::Transformer(const std::pair<const char, std::unique_ptr<Node> >&)>}’
typedef typename f_::type type;
If use of boost-iterator is not mandatory, you can write your own iterator. I'm posting one, which satisfies ForwardIterator. You can expand it to BidirectionalIterator trivially (it may be a bit tedious, however).
Before posting it, I'm afraid I couldn't fulfill your reqirement (aside from use of boost-iterator); std::pair<char, const Node*> is used instead of std::pair<char, const Node&> because the latter prohibits copying. Maybe this is what prevented you from compiling your boost::transform_iterator example (I'm not certain; I'm not so familiar with boost-iterator).
Anyway, here is the code.cpp (125 lines long). main function for testing included:
#include <unordered_map>
#include <memory>
class Node;
template <class Map>
class MyIterator {
public:
// iterator member typedefs
using iterator_category = std::forward_iterator_tag;
using value_type = std::pair<char, const Node*>;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
// typedef for underlying iterator
using underlying_iterator = typename Map::const_iterator;
// constructors
// takes an underlying iterator
explicit MyIterator(underlying_iterator it) : _it(std::move(it)) {}
// default constructor; required by ForwardIterator
MyIterator() = default;
// dereference; required by InputIterator
reference operator*() {
update();
return _p;
}
// dereference; required by InputIterator
pointer operator->() {
update();
return &_p;
}
// increment; required by Iterator
MyIterator<Map>& operator++() {
++_it;
return *this;
}
// increment; required by InputIterator
MyIterator<Map> operator++(int) {
auto mit = *this;
++*this;
return mit;
}
// comparison; required by EqualityComparable
bool operator==(const MyIterator<Map>& mit) const {
return _it == mit._it;
}
// comparison; required by InputIterator
bool operator!=(const MyIterator<Map>& mit) const {
return !(*this == mit);
}
private:
// this method must be called at dereference-time but not
// traverse-time in order to prevent UB at a wrong time.
void update() {
_p = value_type{_it->first, &*(_it->second)};
}
// the underlying iterator that tracks the map
underlying_iterator _it;
// the pair of the desired type. without it, e.g. operator-> doesn't
// work; it has to return a pointer, and the pointed must not be a
// temporary object.
value_type _p;
};
class Node {
public:
typedef std::unique_ptr<Node> ptr_type;
typedef std::unordered_map<char, ptr_type> map_type;
typedef MyIterator<map_type> const_iterator;
const_iterator begin() const {
return const_iterator{_children.begin()};
}
const_iterator end() const {
return const_iterator{_children.end()};
}
private:
map_type _children;
// additional members for testing purposes.
public:
Node(std::string name) : _name(std::move(name)) {}
Node(std::string name, map_type&& children) :
_children(std::move(children)), _name(std::move(name)) {}
std::string const& name() const {
return _name;
}
private:
std::string _name;
};
#include <iostream>
// test program; construct a simple tree and print children.
int main() {
typedef std::unique_ptr<Node> ptr_type;
typedef std::unordered_map<char, ptr_type> map_type;
ptr_type leaf1(new Node("leaf1"));
ptr_type leaf2(new Node("leaf2"));
ptr_type leaf3(new Node("leaf3"));
map_type branch;
branch.emplace('1', std::move(leaf1));
branch.emplace('2', std::move(leaf2));
branch.emplace('3', std::move(leaf3));
Node parent("parent", std::move(branch));
for (auto it = parent.begin(); it != parent.end(); ++it) {
std::cout << it->first << ' ' << it->second->name() << '\n';
}
return 0;
};
compilation command:
g++ -std=c++11 -g -O2 -Wall code.cpp
my output:
3 leaf3
2 leaf2
1 leaf1
MyIterator is written as a template class so that when you want to change std::unordered_map to e.g. std::map, you don't need to modify MyIterator ;)
What complicates things is that the operator* must return a reference to an std::pair; it means that there must exist a (non-temporary) object of std::pair somewhere, otherwise that reference becomes a dangling reference. Same for the operator-> (replace "reference" by "pointer").
Here, MyIterator::_p is the std::pair whose reference is taken. This is copy-assigned upon updates, which std::pair<char, const Node&> (pair containing a reference) prohibits.
Alternatives to std::pair<char, const Node&> are std::pair<char, const Node*> or std::pair<char, std::reference_wrapper<const Node>>. Replace it->second->name() by it->second.get().name() if you choose to use std::reference_wrapper alternative.
I think this might be the reason boost::indirect_iterator exists. Adapting an example from the boost documentation on a (trivial) map<char, char *>:
#include <iostream>
#include <map>
#include <boost/iterator/indirect_iterator.hpp>
int main() {
char characters[] = "abcdefg";
size_t ncharacters = sizeof characters - 1;
char *charptr[ncharacters];
for (size_t i = 0; i < ncharacters; ++i) {
charptr[i] = &characters[i];
}
std::map <char, char *> map1;
for (size_t i = 0; i < ncharacters; ++i) {
map1[characters[i]] = charptr[i]; /* Trivial, just to demonstrate */
}
boost::indirect_iterator<char * const*, char const> const_indirect_first(charptr),
const_indirect_last(charptr + ncharacters);
std::copy(const_indirect_first, const_indirect_last, std::ostream_iterator<char>(std::cout, " "));
std::cout << std::endl;
return 0;
}

Conversion between custom iterator and custom constant iterator

I am working on generic two-dimensional container with custom iterators.
Now I am trying to have one begin() and one end() function for both my iterator and constant_iterator type.
My custom iterator is inside my template Matrix class (but I put them here separately for the sake of the clarity).
template <class T>
class Matrix {
#pragma mark PUBLIC TYPEDEFS
public:
typedef T value_type;
typedef std::size_t size_type;
//typedef typename T::size_type size_type;
//typedef T::size_type size_type;
#pragma mark -
#pragma mark PRIVATE TYPEDEFS
private:
typedef T* pointer_type;
typedef T** storage_type;
#pragma mark -
#pragma mark PRIVATE VARIABLES
private:
size_type width_;
size_type height_;
storage_type data_;
// private iterators
Iterator<T*, T> m_iterator_;
Iterator<const T*, const T> m_const_iterator_;
H_Iterator<T*, T> m_hiterator_;
H_Iterator<const T*, const T> m_const_hiterator_;
#pragma mark -
#pragma mark PUBLIC VARIABLES & TYPEDEFS
public:
typedef Iterator<T*, T> iterator_type;
typedef Iterator<const T*, const T> const_iterator_type;
typedef H_Iterator<T*, T> hiterator;
typedef H_Iterator<const T*, const T> const_hiterator;
#pragma mark -
#pragma mark CONSTRUCTORS & DESTRUCTORS
public:
explicit Matrix(const std::string& fileName) {
}
Matrix(const size_type& width, const size_type& height) : width_(width),
height_(height),
data_(CreateMatrix(width, height)),
m_iterator_(*data_, width, height),
m_const_iterator_(*data_, width, height),
m_hiterator_(*data_, width, height),
m_const_hiterator_(*data_, width, height),
// fill the created matrix with default values of "T"
for (Matrix<T>::iterator_type it = this->begin(); it != this->end(); ++it)
*it = T();
}
~Matrix() {
delete [] data_[0]; // because in data_[0] is array of value_type
delete [] data_;
}
#pragma mark -
#pragma mark PRIVATE METHODS
private:
storage_type CreateMatrix(const size_type width, const size_type height) {
storage_type d = new pointer_type[height]; // array with pointers pointing to rows inside the "block"
pointer_type block = new value_type[width * height]; // one block of memory to store the data
for (size_type row = 0; row < height; ++row)
d[row] = &block[row * width];
return d;
}
#pragma mark -
#pragma mark PUBLIC METHODS
public:
hiterator h_begin(size_type row) { return m_hiterator_.begin(row); }
hiterator h_end(size_type row) { return m_hiterator_.end(row); }
const_hiterator ch_begin(size_type row) { return m_const_hiterator_.begin(row); }
const_hiterator ch_end(size_type row) { return m_const_hiterator_.end(row); }
And my inner Iterator class + derived H_Iterator class (H_Iterator class is for looping through one row of matrix from left to right)
#pragma mark ITERATOR CLASSES
template <typename P, typename V> // "P" - PointerType; "V" - ValueType
class Iterator : public std::iterator<std::forward_iterator_tag, T> {
protected:
P itData_;
size_type w_; // width of the matrix
size_type h_; // height of the matrix
public:
Iterator(P d, size_type width, size_type height) : itData_(d), w_(width), h_(height) { }
Iterator() { }
public:
V& operator*() const {
return *itData_;
}
Iterator<P, V>& operator++() {
++itData_;
return *this;
}
Iterator<P, V>& operator= (T value) {
*itData_ = value;
return *this;
}
P operator->() {
return itData_;
}
friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
return !(lhs.itData_ != rhs.itData_);
}
friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
return !(lhs.itData_ == rhs.itData_);
}
Iterator<P, V> begin() { return Iterator<P, V>(itData_, w_, h_); }
Iterator<P, V> end() { return Iterator<P, V>(itData_ + w_ * h_, w_, h_); };
};
template <typename P, typename V> // "P" - PointerType; "V" - ValueType
class H_Iterator : public Iterator<P, V> {
public:
H_Iterator(P d, size_type width, size_type height) : Iterator<P, V>(d, width, height) { }
H_Iterator() { }
public:
H_Iterator<P, V> begin(size_type row) { return H_Iterator<P, V>(this->itData_ + this->w_ * row, this->w_, this->h_); }
H_Iterator<P, V> end(size_type row) { return H_Iterator<P, V>(this->itData_ + this->w_ * row + this->w_, this->w_, this->h_); };
};
Currently if I want to loop through one of the rows using constant iterator I must do it like this (=I must use begin and end function that was made specifically for constant_hiterator - ch_begin() and ch_end()):
Matrix<int> m (5, 5);
for (Matrix<int>::const_hiterator hit = m.ch_begin(row); hit != m.ch_end(row); ++hit) {
cout << *hit << " ";
}
I am struggling to have only one begin() and end() function for both my const_hiterator and hiterator. So I can write iterators code similarly like iterators for std::vector:
std::vector<int> vector;
for (std::vector<int>::const_iterator it = vector.begin(); it != vector.end(); ++it) { }
for (std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it) { }
I assume that I should have some type of conversion between hiterator and const_hiterator.
There are some heavy head-winds that throw a few monkey wrenches here. Actually, it is common for custom containers to have separate begin() and end() iterators for mutable and constant iterators for one very simple reason, best demonstrated by the following example. This example demonstrates the typical container/iterator semantics that the C++ library implements, and is generally desired for custom container/iterators to implement the same way:
class CustomContainer {
public:
class const_iterator {
// ...
};
class iterator : public const_iterator {
// ...
};
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
};
The standard container/iterator semantics don't use separate begin() and end() methods for mutable and constant iterators. Rather, object.begin(), or pointer->begin() ends up invoking either the constant or the mutable version of begin() depending upon whether object or pointer is a reference/pointer to a mutable or a const instance of the class.
In summary:
1) A mutable iterator begin()/end() methods get called for mutable instances of the class.
2) A begin()/end() on a const instance of a class can only return the constant iterator type. If your begin()/end() operator would return mutable iterators when invoked on a const class instance, then this makes it possible to modify a const instance of the class by simply instantiating its mutable iterators!
3) It is strongly desired for a mutable iterator to be a subclass of the const iterator. This is the easiest way to automatically support passing a mutable iterator to a function or a method that only requires a const iterator parameter (it is also possible to implement that by defining and implementing an overload cast operator, but using subclasses is much easier, and typically results in better performance).
Now, certainly it would be convenient to have a single begin()/end() implementation. And it's not like there's legal requirement that mandates one to always properly support the typical iterator semantics.
But, correctly supporting these expected iterator semantics makes it much easier to leverage all the algorithms in the C++ library, and have them work correctly, with no surprises.
It is certainly possible to declare both mutable and constant begin() and end() methods as wrappers around a private factory that produces a mutable beginning or an ending iterator, with the constant begin()/end() facades degrading it to a constant iterator before returning it. That would be one possible approach. It's not ideal, since the private factory has to be a constant method, in order for it to be invokable from the constant begin()/end() wrappers.

Insert order std::map

I would create an associative array (like std:: map) that stores the elements in order of insertion. I wrote this class:
template <typename K, typename V>
class My_Map : public std::unordered_map<K,V>
{
public:
V& operator[]( const K&& key )
{
typename std::unordered_map<K,V>::iterator __i = find(key);
if (__i == std::unordered_map<K,V>::end()) //se non l'ho trovato...
{
__i = insert(__i, std::make_pair(std::move(key), V()) );
mHistory.push_back(__i);std::cout<<"Sto inserendo: "<<key<<std::endl;
}
return (*__i).second;
}
typename std::unordered_map<K,V>::iterator cbegin() const
{
return *mHistory.cbegin();
}
typename std::unordered_map<K,V>::iterator cend() const
{
return *mHistory.cend();
}
private:
std::list<typename std::unordered_map<K,V>::iterator> mHistory;
};
using namespace std;
int main()
{
My_Map<string,int> myMap;
myMap["1"] = 1;
myMap["23"] = 23;
myMap["-3"] = 3;
myMap["23"] = 28;
myMap["last element"] = 33;
for (auto x = myMap.cbegin(); x != myMap.cend(); ++x)//{std::cout<<"sn dentro\n";}
cout<<(*x).first <<"\t"<<x->second<<endl;
}
I used unordered_map instead std::map because std::map mix iterators when I insert new element.
This code have a problem: the for in main() fails with a segmentation fault. The iterators passed with cbegin() and cend() are not valid...why? What's wrong?
The first thing is that you can't dereference an end iterator of a list. Secondly, I also doubt if yourMap.cend will be necessarily reachable from yourMap.cbegin.
It looks like you might need an adaptor for the list iterator that automatically dereferences the stored map iterator pointer to map item.
In any case, you need to iterate over the list, not from a random point in the unordered_map to another random point therein.
Also: adding elements can cause rehashing, which will invalidate iterators (but not pointers or references to elements). You should not even store iterators into an unordered_map.