c++ 11 standard template (STL) STD:: set (III)

Posted by StewardManscat on Sun, 12 Dec 2021 16:11:53 +0100

iterator

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

std::set<Key,Compare,Allocator>::begin,
std::set<Key,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) 

Returns an iterator pointing to the first element of the container.

If container is empty, iterator returned will be equal to.

Parameters (none)

The return value} points to the iterator of the first element.

Complexity constant.

be careful

Because iterator and Const_ Iterators are constant iterators (and can actually be of the same type), so it is impossible to modify container elements through iterators returned by any of these member functions.

Returns an iterator pointing to the end of the container

std::set<Key,Compare,Allocator>::end, 
std::set<Key,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.

Parameters (none)

The return value} points to the iterator followed by the last element.

Complexity constant.

be careful

Because iterator and Const_ Iterators are constant iterators (and can actually be of the same type), so it is impossible to modify container elements through iterators returned by any of these member functions.

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

std::set<Key,Compare,Allocator>::rbegin, 
std::set<Key,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.

 

Parameters (none)

The return value} points to the inverse iterator of the first element.

Complexity constant.

be careful

Because iterator and Const_ Iterators are constant iterators (and can actually be of the same type), so it is impossible to modify container elements through iterators returned by any of these member functions.

Returns the inverse iterator pointing to the front end

std::set<Key,Compare,Allocator>::rend, 
std::set<Key,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.

Parameters (none)

The return value} points to the inverse iterator of the last element.

Complexity constant.

be careful

Because iterator and Const_ Iterators are constant iterators (and can actually be of the same type), so it is impossible to modify container elements through iterators returned by any of these member functions

Example

    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "const_iterator:   ";
    for (std::set<char>::const_iterator it = set1.cbegin(); it != set1.cend(); it++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    std::cout << "const_reverse_iterator:   ";
    for (std::set<char>::const_reverse_iterator it = set1.crbegin(); it != set1.crend(); it ++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

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

Search

Returns the number of elements that match a specific key

std::set<Key,Compare,Allocator>::count
size_type count( const Key& key ) const;        (1)  

template< class K > size_type count( const K& x ) const;        (2) (C++14 rise) 

Returns the number of elements with key comparison equivalent to the specified parameter, which is 1 or 0 because this container does not allow repetition.

1) Returns the number of elements with key keys.

2) Returns the number of elements with a Key comparison equivalent to the value x. This overload is only available if there is a qualified id Compare::is_transparent is legal and refers to a type to participate in overload resolution. This allows this function to be called without constructing an instance of the Key.

parameter

key-The key value of the number of elements to be measured
x-Alternate value to compare with key

Return value

The number of key elements with a comparison equivalent to key or x, which is 1 or 0 for (1).

Complexity

Logarithmic to container size.

Example

    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "count A: " << set1.count('A') << std::endl;
    std::cout << "count F: " << set1.count('F') << std::endl;

Find elements with specific keys

std::set<Key,Compare,Allocator>::find
iterator find( const Key& key );                 (1)  

const_iterator find( const Key& key ) const;     (2)  

template< class K > iterator find( const K& x ); (3) (C++14 rise) 

template< class K > const_iterator find( const K& x ) const; (4) (C++14 rise) 

1,2) find the element whose key is equal to key.

3,4) find the Key and compare the elements equivalent to the value x. This overload is limited only if id Compare::is_transparent is legal and refers to type to participate in overload resolution. This function is allowed to be called without constructing an instance of the Key.

parameter

key-Element key value to search
x-Any type of value that can be compared transparently with a key

Return value

Iterator pointing to an element whose key is equal to key. If such an element is not found, a trailing (see) iterator is returned.

Complexity

Logarithmic to container size.

Example

    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "find A: " << (set1.find('A') != set1.end() ? "true" : "false") << std::endl;
    std::cout << "find F: " << (set1.find('F') != set1.end() ? "true" : "false") << std::endl;

Returns the range of elements that match a specific key

std::set<Key,Compare,Allocator>::equal_range
std::pair<iterator,iterator> equal_range( const Key& key ); (1)  

std::pair<const_iterator,const_iterator> equal_range( const Key& key ) const;(2)  

template< class K >std::pair<iterator,iterator> equal_range( const K& x ); (3) (C++14 rise) 

template< class K >std::pair<const_iterator,const_iterator> equal_range( const K& x ) const; (4) (C++14 rise) 

Returns the range of all elements in the container that have a given key. The range is defined by two iterators, one pointing to the first element not less than key and the other pointing to the first element greater than key. The first iterator can be obtained interchangeably, while the second iterator can be obtained interchangeably.

1,2) compare key with key.

3,4) compare the Key value with x. This overload is only available if there is a qualified id Compare::is_transparent is legal and refers to a type to participate in overload resolution. They allow this function to be called without constructing an instance of the Key.

This section is not completed
Reason: explain why it's better

parameter

key-Key values of elements to compare
x-Alternative value that can be compared with Key

Return value

With a pair of iterators defining the required range: the first points to the first element not less than key, and the second points to the first element greater than key.

If no element is less than key, the trailing (see) iterator is returned as the first element. Similarly, if no element is greater than key, the trailing iterator is returned as the second element.

Complexity

Logarithmic to container size.

Example

    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::pair<std::set<char>::iterator, std::set<char>::iterator> range = set1.equal_range('C');
    std::cout << "range.first:  " << *range.first << std::endl;
    std::cout << "range.second: " << *range.second << std::endl;

Returns an iterator pointing to the first element not less than the given key

std::set<Key,Compare,Allocator>::lower_bound
iterator lower_bound( const Key& key );            (1)  

const_iterator lower_bound( const Key& key ) const;(1)  

template< class K >iterator lower_bound(const K& x);(2) (C++14 rise) 

template< class K >const_iterator lower_bound(const K& x) const;(2) (C++14 rise) 

1) Returns an iterator pointing to the first element not less than key.

2) Returns an iterator pointing to the first element with a comparison value of not less than x. This overload is only available if there is a qualified id Compare::is_transparent is legal and refers to a type to participate in overload resolution. They allow this function to be called without constructing an instance of the Key.

parameter

key-Key value to compare with element
x-Alternative value that can be compared with Key

Return value

Iterator pointing to the first element not less than key. If such an element is not found, a trailing iterator is returned (see).

Complexity

Logarithmic to container size.

Returns an iterator pointing to the first element greater than the given key

std::set<Key,Compare,Allocator>::upper_bound
iterator upper_bound( const Key& key );            (1)  

const_iterator upper_bound( const Key& key ) const; (1)  

template< class K >iterator upper_bound( const K& x );(2) (C++14 rise) 

template< class K >const_iterator upper_bound( const K& x ) const;(2) (C++14 rise) 

1) Returns an iterator pointing to the first element greater than key.

2) Returns an iterator pointing to the first element with a comparison value greater than x. This overload is only available if there is a qualified id Compare::is_transparent is legal and refers to a type to participate in overload resolution. This allows this function to be called without constructing an instance of the Key.

parameter

key-Key value compared with element
x-Alternative value that can be compared with Key

Return value

Iterator pointing to the first element greater than key. If such an element is not found, a trailing (see) iterator is returned.

Complexity

Logarithmic to container size.

Example

    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::set<char>::iterator itLower = set1.lower_bound('C');
    std::cout << "lower_bound('C') : " << *itLower << std::endl;
    std::set<char>::iterator itUpper = set1.upper_bound('C');
    std::cout << "upper_bound('C') : " << *itUpper << std::endl;

Code summary

#include <set>
#include <iostream>
#include <ios>
#include <string>
#include <vector>
#include <algorithm>
#include <typeinfo>

// Print container elements
template <typename T, typename _Compare = std::less<T>>
void printSet(const std::string &name, const std::set<T, _Compare> &setP)
{
    std::cout << name << " :    ";
    for (auto s : setP)
    {
        std::cout << s << ' ';
    }

    std::cout << std::endl;
}

// Custom comparison
struct myGreaterCompare
{
    myGreaterCompare() {}
    template < typename T>
    bool operator()(const T &a, const T &b)const
    {
        return a > b;
    }
};

void constructor()
{
    std::cout << "constructor start " << std::endl;
    // c++11 initialization container list syntax:
    // Default ascending order
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    printSet("default       ", set1);
    // Increasing
    std::set<char, std::less<char>> set2{'A', 'B', 'C', 'D', 'E'};
    printSet("std::less<>   ", set2);
    // Diminishing
    std::set<char, std::greater<char>> set3{'A', 'B', 'C', 'D', 'E'};
    printSet("std::greater<>", set3);
    // Custom comparison function
    std::set<char, myGreaterCompare> set4{'A', 'B', 'C', 'D', 'E'};
    printSet("myGreaterCompare", set4);

    // Copy constructor, set < T > must be of the same type, including comparison
    std::set<char, std::greater<char>> set5(set3);
    printSet("copy constructor", set5);

    // Assignment constructor, set < T > must be of the same type, including comparison
    std::set<char, std::less<char>> set6 = set2;
    printSet("assignment constructor", set6);

    // Range construction
    std::set<char, myGreaterCompare> set7(set6.begin(), set6.end());
    printSet("range constructor", set7);
    std::cout << "constructor end " << std::endl << std::endl;
}

void capacity()
{
    std::cout << "capacity start " << std::endl;

    // Check that the container has no elements
    std::set<char> set1;
    std::cout << "set1 is empty ? :   " << (set1.empty() ? "empty" : "no empty") << std::endl;
    set1.insert('A');
    std::cout << "set1 is empty ? :   " << (set1.empty() ? "empty" : "no empty") << std::endl;

    // Returns the number of elements in the container
    std::set<char> set2;
    std::cout << "set2 size : " << set2.size() << std::endl;
    set2 = std::set<char> {'A', 'B', 'C', 'D', 'E'};
    std::cout << "set2 size : " << set2.size() << std::endl;

    // Returns the maximum number of elements that a container can hold based on system or library implementation restrictions
    std::set<char> set3;
    std::cout << "std::set<char> max_size() : " << set3.max_size() << std::endl;
    std::set<int> set4;
    std::cout << "std::set<int> max_size() : " << set4.max_size() << std::endl;
    std::set<std::string> set5;
    std::cout << "std::set<std::string> max_size() : " << set5.max_size() << std::endl;
    std::set<double> set6;
    std::cout << "std::set<double> max_size() : " << set6.max_size() << std::endl;
    std::cout << "capacity end " << std::endl << std::endl;
}

void compareFunc()
{
    // Function object that returns the comparison value
    std::cout << "observer start " << std::endl;
    std::set<char> set1;
    std::cout << "std::set<char> key_comp() : "
              << typeid(set1.key_comp()).name() << std::endl;
    // Compare the size of 'A' and 'B', and 'A' is smaller than 'B'
    std::cout << "std::less<> compare('A','B') :  " <<
              (set1.key_comp()('A', 'B') ? "true" : "false") << std::endl;

    std::set<char, std::greater<char>> set2;
    std::cout << "std::set<char, std::greater<char>> key_comp() : "
              << typeid(set2.key_comp()).name() << std::endl;
    // Compare the size of 'A' and 'B', and 'A' is larger than 'B'
    std::cout << "std::greater<> compare('A','B') :  " <<
              (set1.key_comp()('A', 'B') ? "true" : "false") << std::endl;

    std::set<char, myGreaterCompare> set3;
    std::cout << "std::set<char, myGreaterCompare> key_comp() : "
              << typeid(set3.key_comp()).name() << std::endl;

    std::cout << "observer end " << std::endl << std::endl;
}

void clearTest()
{
    std::cout << "clearTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "set1 size: " << set1.size() << std::endl;
    set1.clear();
    std::cout << "clear after set1 size: " << set1.size() << std::endl;
    std::cout << "clearTest end " << std::endl << std::endl;
}

void insertTest()
{
    std::cout << "insertTest start " << std::endl;
    std::set<char> set1;
    std::pair<std::set<char>::iterator, bool> it = set1.insert('A');
    std::cout << "insert 'A' " << (it.second ? "true" : "false") << std::endl;
    it = set1.insert('A');
    std::cout << "insert 'A' " << (it.second ? "true" : "false") << std::endl;

    std::set<char>::const_iterator itb = set1.cbegin();
    std::set<char>::const_iterator itp = set1.insert(itb, 'B');
    std::cout << "insert 'B' : " << *itp << std::endl;

    std::vector<char> arr{'A', 'B', 'C', 'D', 'E'};
    set1.insert(arr.begin(), arr.end());
    printSet("range insert ", set1);

    std::cout << "insertTest end " << std::endl << std::endl;
}

void emplaceTest()
{
    std::cout << "emplaceTest start " << std::endl;
    std::set<char> set1;
    char ch = 'A';
    while (ch != 'C')
    {
        set1.emplace(ch);
        ch++;
    }
    printSet("emplace", set1);

    std::set<char>::const_iterator it = set1.find('B');
    set1.emplace_hint(it, 'D');
    printSet("emplace_hint", set1);

    std::cout << "emplaceTest end " << std::endl << std::endl;
}

void eraseTest()
{
    std::cout << "eraseTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    printSet("erase before", set1);
    std::set<char>::const_iterator it = set1.find('C');
    set1.erase(it);
    printSet("erase(it)", set1);
    set1.erase(set1.find('A'), set1.find('D'));
    printSet("erase() range", set1);
    set1.erase('D');
    printSet("erase() value", set1);
    std::cout << "eraseTest end " << std::endl << std::endl;
}

void swapTest()
{
    std::cout << "swapTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C'};
    std::set<char> set2{'D', 'E'};
    std::cout << "swap() before" << std::endl;
    printSet("set1", set1);
    printSet("set2", set2);
    set1.swap(set2);
    std::cout << "swap() after" << std::endl;
    printSet("set1", set1);
    printSet("set2", set2);
    std::cout << "swapTest end " << std::endl << std::endl;
}

void iteratorTest()
{
    std::cout << "iteratorTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "const_iterator:   ";
    for (std::set<char>::const_iterator it = set1.cbegin(); it != set1.cend(); it++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    std::cout << "const_reverse_iterator:   ";
    for (std::set<char>::const_reverse_iterator it = set1.crbegin(); it != set1.crend(); it ++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

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

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


void countTest()
{
    std::cout << "countTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "count A: " << set1.count('A') << std::endl;
    std::cout << "count F: " << set1.count('F') << std::endl;
    std::cout << "countTest end " << std::endl << std::endl;
}

void findTest()
{
    std::cout << "findTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::cout << "find A: " << (set1.find('A') != set1.end() ? "true" : "false") << std::endl;
    std::cout << "find F: " << (set1.find('F') != set1.end() ? "true" : "false") << std::endl;
    std::cout << "findTest end " << std::endl << std::endl;
}

void equal_rangeTest()
{
    std::cout << "equal_rangeTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::pair<std::set<char>::iterator, std::set<char>::iterator> range = set1.equal_range('C');
    std::cout << "range.first:  " << *range.first << std::endl;
    std::cout << "range.second: " << *range.second << std::endl;
    std::cout << "equal_rangeTest end " << std::endl << std::endl;
}

void boundTest()
{
    std::cout << "boundTest start " << std::endl;
    std::set<char> set1{'A', 'B', 'C', 'D', 'E'};
    std::set<char>::iterator itLower = set1.lower_bound('C');
    std::cout << "lower_bound('C') : " << *itLower << std::endl;
    std::set<char>::iterator itUpper = set1.upper_bound('C');
    std::cout << "upper_bound('C') : " << *itUpper << std::endl;
    std::cout << "boundTest end " << std::endl << std::endl;
}

int main()
{
//    constructor();
//    capacity();
//    compareFunc();
//    clearTest();
//    insertTest();
//    emplaceTest();
//    eraseTest();
//    swapTest();
    iteratorTest();
    countTest();
    findTest();
    equal_rangeTest();
    boundTest();
    return 0;
}

 

Topics: C++ Back-end