c++ 11 standard template (STL) STD:: Map (II)

Posted by jameslynns on Sun, 02 Jan 2022 17:47:31 +0100

iterator

Returns an iterator that points to the first element of the container

std::map<Key,T,Compare,Allocator>::begin, 
std::map<Key,T,Compare,Allocator>::cbegin
iterator begin();                                        (C++11 front) 

iterator begin() noexcept;                               (C++11 rise) 

const_iterator begin() const;                            (C++11 front) 

const_iterator begin() const noexcept;                   (C++11 rise) 

const_iterator cbegin() const noexcept;                  (C++11 rise) 

 

parameter

(none)

Return value

Iterator pointing to the first element.

Complexity

Constant.

Returns an iterator pointing to the end of the container

std::map<Key,T,Compare,Allocator>::end, 
std::map<Key,T,Compare,Allocator>::cend
iterator end();                                     (C++11 front) 

iterator end() noexcept;                            (C++11 rise) 

const_iterator end() const;                         (C++11 front) 

const_iterator end() const noexcept;                (C++11 rise) 

const_iterator cend() const noexcept;               (C++11 rise) 

Returns an iterator that points to the element following the last element of the container.

This element is represented as a placeholder; Attempting to access it resulted in undefined behavior.

 

parameter

(none)

Return value

Point to the iterator that follows the last element.

Complexity

Constant.

Returns the inverse iterator pointing to the last element of the container

std::map<Key,T,Compare,Allocator>::rbegin,
std::map<Key,T,Compare,Allocator>::crbegin

 

reverse_iterator rbegin();                                             (C++11 front) 

reverse_iterator rbegin() noexcept;                                    (C++11 rise) 

const_reverse_iterator rbegin() const;                                 (C++11 front) 

const_reverse_iterator rbegin() const noexcept;                        (C++11 rise) 

const_reverse_iterator crbegin() const noexcept;                       (C++11 rise) 

Returns an inverse iterator that points to the first element of the inverse container. It corresponds to the last element of a non reverse container.

 

parameter

(none)

Return value

Inverse iterator pointing to the first element.

Complexity

Constant.

Returns the inverse iterator pointing to the front end

std::map<Key,T,Compare,Allocator>::rend,
 std::map<Key,T,Compare,Allocator>::crend
reverse_iterator rend();                                (C++11 front) 

reverse_iterator rend() noexcept;                       (C++11 rise) 

const_reverse_iterator rend() const;                    (C++11 front) 

const_reverse_iterator rend() const noexcept;           (C++11 rise) 

const_reverse_iterator crend() const noexcept;          (C++11 rise) 

Returns an inverse iterator pointing to the last element of the inverse container. It corresponds to the previous element of the non reverse container header element. This element behaves as a placeholder and attempts to access it result in undefined behavior.

parameter

(none)

Return value

An inverse iterator that points to the last element after the last element.

Complexity

Constant.

Example

 map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    // Traversal container, const_iterator
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_iterator it = map1.cbegin(); it != map1.cend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_reverse_iterator it = map1.crbegin(); it != map1.crend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }

    std::cout << "begin():   " << std::hex << (int)&*map1.begin() << std::endl;
    std::cout << "cbegin():  " << std::hex << (int)&*map1.cbegin() << std::endl;
    std::cout << "end():     " << std::hex << (int)&*map1.end() << std::endl;
    std::cout << "cend():    " << std::hex << (int)&*map1.cend() << std::endl;
    std::cout << "rbegin():  " << std::hex << (int)&*map1.rbegin() << std::endl;
    std::cout << "crbegin(): " << std::hex << (int)&*map1.crbegin() << std::endl;
    std::cout << "rend():    " << std::hex << (int)&*map1.rend() << std::endl;
    std::cout << "crend():   " << std::hex << (int)&*map1.crend() << std::endl;

 

Modifier

Clear content

std::map<Key,T,Compare,Allocator>::clear
void clear();                     (C++11 front) 

void clear() noexcept;            (C++11 rise) 

Erase all elements from the container. size() returns zero after this call.

Illegal any reference, pointer, or iterator that refers to the contained element. Any trailing iterators remain valid.

parameter

(none)

Return value

(none)

Complexity

It is linear with the container size, that is, the number of elements.

Example

    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("clear before", map1);
    map1.clear();
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");

Insert element or node

std::map<Key,T,Compare,Allocator>::insert
std::pair<iterator,bool> insert( const value_type& value );           (1) 
template< class P > std::pair<iterator,bool> insert( P&& value );    (2)

Insert value. Overload (2) is equivalent to empty (STD:: forward < p > (value)), and only if STD:: is_ constructible<value_ Type, P & & >:: value = = true to participate in overload resolution.

Returns a pair consisting of an iterator pointing to the inserted element (or an iterator blocking the inserted element) and a bool indicating whether the insertion occurred.

If any operation throws an exception, the insertion has no effect (strong exception guarantee).

Log to container size, O(log(size())).

iterator insert( iterator hint, const value_type& value );            (C++11 front) 

iterator insert( const_iterator hint, const value_type& value );      (C++11 rise) 

template< class P >
 iterator insert( const_iterator hint, P&& value );                  (5) (C++11 rise) 

Insert value as close as possible, just before (C++11) hint. Overload (4) is equivalent to empty_ Hint (hint, STD:: forward < p > (value)), and only if STD:: is_ constructible<value_ Type, P & & >:: value = = true to participate in overload resolution.

Returns an iterator that points to the inserted element or to an element that prevents insertion.

If the insertion occurs just after the hint, it is an equal sharing constant, otherwise it is logarithmic to the container size. (before C++11)

If the insertion occurs just before the hint, it is an equal sharing constant, otherwise it is logarithmic to the container size. (from C++11)

void insert( std::initializer_list<value_type> ilist );        (8) (C++11 rise) 

Insert from initializer_list ilist element. If more than one element in the scope has a more equivalent key, which element to insert is unspecified

If any operation throws an exception, the program is in a legal state (basic exception guarantee).

O(N*log(size() + N)), where N is the number of elements to insert.

parameter

hint-

Iterator used as a suggestion for the start of the search

(before C++11)

The iterator that points to the position before which the new element will be inserted

(from C++11)
value-Value to insert
first, last-Range of elements to insert
ilist-Initializer to insert value source_ list

Example

    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("insert before", map1);
    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.insert({4, "D"});
    cout << "insert " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("insert after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    cout << "find key: " << pIt->first << " value: " << pIt->second << endl;

    map<uint16_t, string>::const_iterator nIt = map1.insert(pIt, {5, "E"});
    cout << "insert key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("insert after", map1);

    map<uint16_t, string> map2{{6, "F"}, {7, "H"}};
    map2.insert(map1.begin(), map1.end());
    print_Map("map2 insert after", map2);

In situ structural elements

std::map<Key,T,Compare,Allocator>::emplace
template< class... Args >
std::pair<iterator,bool> emplace( Args&&... args );        (C++11 rise) 

If there is no element with the key in the container, insert a new element constructed in situ with the given args into the container.

Careful use of empty allows you to construct new elements while avoiding unnecessary copying or moving operations. Use STD:: forward < args > (args) Forward the constructor that calls the new element (i.e. STD:: pair < const key, t >). Even if the key element already exists in the container, the element may be constructed. In this case, the newly constructed element will be destroyed immediately.

No iterators or references are illegal.

parameter

args-Parameters to forward to the element constructor

Return value

Returns the iterator pointing to the inserted element, or the existing element if no insertion occurs, and the bool indicating whether the insertion occurs (true if insertion occurs, otherwise false).

abnormal

If any operation throws an exception, this function has no effect.

Complexity

Logarithmic to container size.

Example

    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("emplace before", map1);

    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.emplace(make_pair(4, "D"));
    cout << "emplace " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("emplace after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator nIt = map1.emplace_hint(pIt, make_pair(5, "E"));
    cout << "emplace_hint key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("emplace_hint after", map1);

Erase element

std::map<Key,T,Compare,Allocator>::erase
void erase( iterator pos );                        (C++11 front) 

iterator erase( const_iterator pos );              (C++11 rise) 

void erase( iterator first, iterator last );       (C++11 front) 

iterator erase( const_iterator first, const_iterator last );(C++11 rise) 

size_type erase( const key_type& key );           (3) 

Removes the specified element from the container.

1) Remove the element at pos.

2) Remove the element in the range [first; last], which must be a legal range in * this.

3) Remove the element with key equal to key (if one exists).

References and iterators to erased elements are illegal. Other references and iterators are not affected.

Iterator pos must be legal and dereferentiable. Thus, the end() iterator (legal but not dereferentiable) cannot be used as the value used by pos.

parameter

pos-Iterator pointing to the element to be removed
first, last-Range of elements to remove
key-Element key to remove

Return value

1-2) followed by the iterator of the last element removed.

3) Number of elements removed.

abnormal

(none) (1,2)

3) Exceptions thrown by any Compare object

Complexity

Instance c of the given map:

1) Sharing constant

2) log(c.size()) + std::distance(first, last)

3) log(c.size()) + c.count(k)

Example

    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("erase before", map1);
    size_t ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator eIt = map1.erase(pIt);
    cout << "erase key: " << eIt->first << " value: " << eIt->second << endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("map2 erase before", map2);
    map2.erase(map2.begin(), map2.end());
    print_Map("map2 erase after", map2);

Exchange content

std::map<Key,T,Compare,Allocator>::swap
void swap( map& other );                    (C++17 front) 

void swap( map& other ) noexcept(/* see below */);    (C++17 rise) 

Exchange content with other. No move, copy, or swap operations are invoked on a single element.

All iterators and references remain legal. The trailing iterator is illegal.

Pred objects must be swappable and exchanged with unqualified calls from non member swap.

If STD:: allocator_ traits<allocator_ type>::propagate_ on_ container_ If swap:: value is true, the allocator is exchanged with the unqualified call of non member swap. Otherwise, do not exchange them (and if get_allocator())= other. get_ Allocator(), the behavior is undefined).

(from C++11)

parameter

other-The container with which to exchange content

Return value

(none)

abnormal

Any exception thrown by the Compare object exchange.

(before C++17)
noexcept stipulates:

noexcept(std::allocator_traits<Allocator>::is_always_equal::value
&& std::is_nothrow_swappable<Compare>::value)

(from C++17)

Complexity

Constant.

Example

    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    map<uint16_t, string> map2{{4, "D"}, {5, "E"}};
    print_Map("map1 swap before", map1);
    print_Map("map2 swap before", map2);
    map1.swap(map2);
    print_Map("map1 swap after", map1);
    print_Map("map2 swap after", map2);

Code summary

#include <iostream>
#include <map>
#include <string>

using namespace std;

struct myCompare
{
    bool operator()(const uint16_t a, const uint16_t b) const
    {
        return (a > b);
    }
    myCompare() {}
};

template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
          typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
void print_Map(const string &name, const map<_Key, _Tp, _Compare, _Alloc> &tmap)
{
    cout << name << ": \n";
    for (const std::pair<const _Key, _Tp> it : tmap)
    {
        cout << "key: " << it.first << ", value: " << it.second << endl;
    }
}

void constructorTest()
{
    cout << "constructorTest() begin" << endl;
    // Construct an empty container
    map<uint16_t, string> map1;
    cout << "map1.size() : " << map1.size() << endl;

    // List initialization, construction, sorting and increment
    map<uint16_t, string, std::less<uint16_t>> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, ASC", map2);
    // List initialization, construction, sorting, decrement
    map<uint16_t, string, std::greater<uint16_t>> map6{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, DESC", map6);
    // List initialization, construction, sorting and customization
    map<uint16_t, string, myCompare> map7{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("initializer_list, DESC", map7);

    // Range construction, sort increment
    map<uint16_t, string, std::less<uint16_t>> map3(map2.begin(), map2.end());
    print_Map("range, ASC", map3);
    // Range construction, sort decrement
    map<uint16_t, string, std::greater<uint16_t>> map8(map2.begin(), map2.end());
    print_Map("range, DESC", map8);


    // The copy structure must be of the same type, including sorting and increasing sorting
    map<uint16_t, string, std::less<uint16_t>> map4(map3);
    print_Map("copy, ASC", map4);
    // Copy construction, sort increment
    map<uint16_t, string, std::greater<uint16_t>> map9(map8);
    print_Map("copy, DESC", map9);

    // Assignment structure, the types must be consistent, including sorting and sorting increment
    map<uint16_t, string, std::less<uint16_t>> map10 = map4;
    print_Map("assignment , ASC", map10);
    // The assignment structure must be of the same type, including sorting and decreasing sorting
    map<uint16_t, string, std::greater<uint16_t>> map11 = map9;
    print_Map("assignment , DESC", map11);

    cout << "constructorTest() end" << endl;
}

void elementAccessTest()
{
    cout << "elementAccessTest() begin" << endl;
    map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    cout << "at(key) : " << map1.at(1) << endl;
    cout << "[key] : " << map1[2] << endl;
    // The map container generates < 6, "" > nodes
    cout << "[key] : " << map1[6] << endl;
    print_Map("[key] , ASC", map1);
    // The map container generates < 7, "H" > nodes
    map1[7] = "H";
    print_Map("[key] , ASC", map1);
    // The node value whose map container key is 1 is replaced with "K"
    map1[1] = "K";
    print_Map("[key] , ASC", map1);
    cout << "elementAccessTest() end" << endl;
}

void capacityTest()
{
    cout << "capacityTest begin" << endl;
    map<uint16_t, string> map1;
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "map1 size() " << map1.size() << endl;;
    map1[1] = "A";
    map1[2] = "B";
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "map1 size() " << map1.size() << endl;;
    cout << "map<uint16_t, string> max_size: " << map1.max_size() << std::endl;
    map<uint16_t, uint16_t> map2;
    cout << "map<uint16_t, uint16_t> max_size: " << map2.max_size() << std::endl;
    map<string, uint16_t> map3;
    cout << "map<string, uint16_t> max_size: " << map3.max_size() << std::endl;
    map<string, string> map4;
    cout << "map<string, string> max_size: " << map4.max_size() << std::endl;
    cout << "capacityTest end" << endl;
}

void iteratorTest()
{
    cout << "iteratorTest begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    // Traversal container, const_iterator
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_iterator it = map1.cbegin(); it != map1.cend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }
    std::cout << "const_iterator:\n";
    for (map<uint16_t, string>::const_reverse_iterator it = map1.crbegin(); it != map1.crend(); it++)
    {
        cout << "key: " << it->first << ", value: " << it->second << endl;
    }

    std::cout << "begin():   " << std::hex << (int)&*map1.begin() << std::endl;
    std::cout << "cbegin():  " << std::hex << (int)&*map1.cbegin() << std::endl;
    std::cout << "end():     " << std::hex << (int)&*map1.end() << std::endl;
    std::cout << "cend():    " << std::hex << (int)&*map1.cend() << std::endl;
    std::cout << "rbegin():  " << std::hex << (int)&*map1.rbegin() << std::endl;
    std::cout << "crbegin(): " << std::hex << (int)&*map1.crbegin() << std::endl;
    std::cout << "rend():    " << std::hex << (int)&*map1.rend() << std::endl;
    std::cout << "crend():   " << std::hex << (int)&*map1.crend() << std::endl;

    cout << "iteratorTest end" << endl;
}

void clearTest()
{
    cout << "clearTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("clear before", map1);
    map1.clear();
    cout << "map1: " << (map1.empty() ? "empty" : "not empty");
    cout << "clearTest() end" << endl;
}

void insertTest()
{
    cout << "insertTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("insert before", map1);
    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.insert({4, "D"});
    cout << "insert " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("insert after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    cout << "find key: " << pIt->first << " value: " << pIt->second << endl;

    map<uint16_t, string>::const_iterator nIt = map1.insert(pIt, {5, "E"});
    cout << "insert key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("insert after", map1);

    map<uint16_t, string> map2{{6, "F"}, {7, "H"}};
    map2.insert(map1.begin(), map1.end());
    print_Map("map2 insert after", map2);
    cout << "insertTest() end" << endl;
}

void emplaceTest()
{
    cout << "emplaceTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    print_Map("emplace before", map1);

    std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.emplace(make_pair(4, "D"));
    cout << "emplace " << (itI.second ? "success" : "fail") ;
    cout << " key: " << itI.first->first << " value: " << itI.first->second <<  endl;
    print_Map("emplace after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator nIt = map1.emplace_hint(pIt, make_pair(5, "E"));
    cout << "emplace_hint key: " << nIt->first << " value: " << nIt->second << endl;
    print_Map("emplace_hint after", map1);

    cout << "emplaceTest() end" << endl;
}

void eraseTest()
{
    cout << "eraseTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("erase before", map1);
    size_t ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    ct = map1.erase(3);
    cout << "erase size: " << ct << std::endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string>::const_iterator pIt = map1.find(2);
    map<uint16_t, string>::const_iterator eIt = map1.erase(pIt);
    cout << "erase key: " << eIt->first << " value: " << eIt->second << endl;
    print_Map("map1 erase after", map1);

    map<uint16_t, string> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
    print_Map("map2 erase before", map2);
    map2.erase(map2.begin(), map2.end());
    print_Map("map2 erase after", map2);
    cout << "eraseTest() end" << endl;
}

void swapTest()
{
    cout << "swapTest() begin" << endl;
    map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
    map<uint16_t, string> map2{{4, "D"}, {5, "E"}};
    print_Map("map1 swap before", map1);
    print_Map("map2 swap before", map2);
    map1.swap(map2);
    print_Map("map1 swap after", map1);
    print_Map("map2 swap after", map2);
    cout << "swapTest() endl" << endl;


}

int main()
{
//    constructorTest();
//    elementAccessTest();
//    capacityTest();
//    iteratorTest();
//    clearTest();
//    insertTest();
//    emplaceTest();
//    eraseTest();
    swapTest();
    return 0;
}

Topics: C++ Back-end