c++ 11标准模板(STL) std::set(一)

template<class Key,class Compare = std::less<Key>, class Allocator = std::allocator<Key>
> class set; (1)  

namespace pmr {
    
    
    template <class Key, class Compare = std::less<Key>>
     using set = std::set<Key, Compare, std::pmr::polymorphic_allocator<Key>>;
} 

std::set 是关联容器,含有 Key 类型对象的已排序集。用比较函数 比较 (Compare) 进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。
在每个标准库使用比较 (Compare) 概念的场所,用等价关系确定唯一性。不精确地说,若二个对象 a 与 b 相互间既不比较大于亦不比较小于: !comp(a, b) && !comp(b, a) ,则认为它们等价。
std::set 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、关联容器 (AssociativeContainer) 和可逆容器 (ReversibleContainer) 的要求。

成员类型
成员类型 定义
key_type Key
value_type Key
size_type 无符号整数类型(通常是 std::size_t )
difference_type 有符号整数类型(通常是 std::ptrdiff_t )
key_compare Compare
value_compare Compare
allocator_type Allocator
reference Allocator::reference (C++11 前)
value_type& (C++11 起)
const_reference Allocator::const_reference (C++11 前)
const value_type& (C++11 起)
pointer Allocator::pointer (C++11 前)
std::allocator_traits::pointer (C++11 起)
const_pointer Allocator::const_pointer (C++11 前)
std::allocator_traits::const_pointer (C++11 起)
iterator 常遗留双向迭代器 (LegacyBidirectionalIterator)
const_iterator 常双向迭代器
reverse_iterator std::reverse_iterator
const_reverse_iterator std::reverse_iterator<const_iterator>

构造函数

// (1)
set();
explicit set( const Compare& comp, const Allocator& alloc = Allocator() );   
explicit set( const Allocator& alloc );			(C++11) 

//(2)  
template< class InputIt >
set( InputIt first, InputIt last, const Compare& comp = Compare(),
    const Allocator& alloc = Allocator() );   

template< class InputIt >
set( InputIt first, InputIt last, const Allocator& alloc)
    : set(first, last, Compare(), alloc) {
    
    }  //(C++14 起) 
    
//  (3)
set( const set& other );
set( const set& other, const Allocator& alloc );		/ (C++11) 

// (4)
set( set&& other );			//(C++11 起) 
set( set&& other, const Allocator& alloc ); (C++11) 

从各种数据源,可选地用用户提供的分配器 alloc 或比较函数对象 comp 构造新容器。

  1. 默认构造函数。构造新容器。
  2. 范围构造函数。构造拥有范围 [first, last) 内容的容器。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的(待决的 LWG2844 )。
  3. 复制构造函数。以 other 内容的副本构造容器。若不提供 alloc ,则通过调用 std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()) 获得分配器。
  4. 移动构造函数。用移动语义构造拥有 other 内容的容器。若不提供 alloc ,则以从属于 other 的分配器移动构造获得分配器。

参数
alloc - 用于此容器所有内存分配的分配器
comp - 用于所有关键比较的比较函数对象
first, last - 复制元素的来源范围

类型要求
InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
Compare 必须满足比较 (Compare) 的要求。
Allocator 必须满足分配器 (Allocator) 的要求。

复杂度

  1. 常数
  2. 通常为 N log(N) ,若范围已经由 value_comp() 排序则与 N 成线性,其中 N = std::distance(first, last) 。
  3. 与 other 的大小成线性。
  4. 常数。若给定 alloc 而 alloc != other.get_allocator() ,则为线性。

异常
调用 Allocator::allocate 可能抛出。
注意
在容器移动构造(重载 (4) )后,指向 other 的引用及迭代器(除了尾迭代器)保持合法,但指代现于 *this 中的元素。当前标准由 [container.requirements.general]/12 中的总括陈述作出此保证,而 LWG 2321 正在考虑更严格的保证。

示例

 // c++11 初始化容器列表语法:
    // 默认升序
    std::set<char> set1{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("default       ", set1);
    // 递增
    std::set<char, std::less<char>> set2{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("std::less<>   ", set2);
    // 递减
    std::set<char, std::greater<char>> set3{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("std::greater<>", set3);
    // 自定义比较函数
    std::set<char, myGreaterCompare> set4{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("myGreaterCompare", set4);

    // 拷贝构造函数, set<T> 必须同类型,包括比较
    std::set<char, std::greater<char>> set5(set3);
    printSet("copy constructor",set5);

    // 赋值构造函数, set<T> 必须同类型,包括比较
    std::set<char, std::less<char>> set6 = set2;
    printSet("assignment constructor", set6);

    // 范围构造
    std::set<char, myGreaterCompare> set7(set6.begin(), set6.end());
    printSet("range constructor", set7);

容量

1、检查容器是否为空

bool empty() const;				//(C++11 前) 
bool empty() const noexcept;	//(C++11 起) (C++20 前) 

检查容器是否无元素,即是否 begin() == end() 。
参数 (无)
返回值 若容器为空则为 true ,否则为 false
复杂度 常数。

2、返回容纳的元素数

size_type size() const;			//(C++11 前) 
size_type size() const noexcept;	//(C++11 起) 

返回容器中的元素数,即 std::distance(begin(), end()) 。
参数 (无)
返回值 容器中的元素数量。
复杂度 常数。

3、返回可容纳的最大元素数

size_type max_size() const;			//(C++11 前) 
size_type max_size() const noexcept;// (C++11 起) 

返回根据系统或库实现限制的容器可保有的元素最大数量,即对于最大容器的 std::distance(begin(), end()) 。
参数 (无)
返回值 元素数量的最大值。
复杂度 常数。
注意
此值通常反映容器大小上的理论极限,至多为 std::numeric_limits<difference_type>::max() 。运行时,可用 RAM 总量可能会限制容器大小到小于 max_size() 的值。

示例

 // 检查容器是否无元素
    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;

    // 返回容器中的元素数
    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;

    // 返回根据系统或库实现限制的容器可保有的元素最大数量
    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;

观察器

1、返回用于比较键的函数

key_compare key_comp() const;

返回用于比较关键的函数对象,它是此容器构造函数参数 comp 的副本,它与 value_comp 相同。
参数 (无)
返回值 比较关键的函数对象。
复杂度 常数
2、返回用于在value_type类型的对象中比较键的函数。

std::set::value_compare value_comp() const;

返回比较值的函数对象。它与 key_comp 相同。

参数 (无)
返回值 比较值的函数对象。
复杂度 常数。

示例

    std::set<char> set1;
    std::cout << "std::set<char> key_comp() : "
              << typeid(set1.key_comp()).name() << std::endl;
    // 比较'A','B'大小,'A'比'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;
    // 比较'A','B'大小,'A'比'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;

代码汇总

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

// 打印容器元素
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;
}

// 自定义比较
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 初始化容器列表语法:
    // 默认升序
    std::set<char> set1{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("default       ", set1);
    // 递增
    std::set<char, std::less<char>> set2{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("std::less<>   ", set2);
    // 递减
    std::set<char, std::greater<char>> set3{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("std::greater<>", set3);
    // 自定义比较函数
    std::set<char, myGreaterCompare> set4{
    
    'A', 'B', 'C', 'D', 'E'};
    printSet("myGreaterCompare", set4);

    // 拷贝构造函数, set<T> 必须同类型,包括比较
    std::set<char, std::greater<char>> set5(set3);
    printSet("copy constructor",set5);

    // 赋值构造函数, set<T> 必须同类型,包括比较
    std::set<char, std::less<char>> set6 = set2;
    printSet("assignment constructor", set6);

    // 范围构造
    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;

    // 检查容器是否无元素
    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;

    // 返回容器中的元素数
    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;

    // 返回根据系统或库实现限制的容器可保有的元素最大数量
    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()
{
    
    
    // 返回比较值的函数对象
    std::cout << "observer start " << std::endl;
    std::set<char> set1;
    std::cout << "std::set<char> key_comp() : "
              << typeid(set1.key_comp()).name() << std::endl;
    // 比较'A','B'大小,'A'比'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;
    // 比较'A','B'大小,'A'比'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;
}

int main()
{
    
    
    constructor();
    capacity();
    compareFunc();
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/121592410