《C++新经典》第19章 STL标准模板库大局观

2023-05-16

《C++新经典》第19章 STL标准模板库大局观

  • 19.1 STL总述、发展史、组成与数据结构谈
    • 19.1.1 几个概念与推荐书籍
    • 19.1.2 算法和数据结构谈
    • 19.1.4 标准库使用
    • 19.1.5 STL的组成部分
  • 19.2 容器分类与array、vector容器精解
    • 19.2.1 容器的分类
    • 19.2.2 容器的说明和简单应用
  • 19.3 容器的说明和简单应用续
    • 19.3.1 deque和stack
    • 19.3.2 queue
    • 19.3.3 list
    • 19.3.4 其它
  • 19.4 分配器简介、使用与工作原理说
    • 19.4.1 分配器简介
    • 19.4.2 分配器的使用
    • 19.4.3 其它的分配器与原理说
  • 19.5 迭代器的概念和分类
    • 19.5.1 迭代器基本概念
    • 19.5.2 迭代器的分类
  • 19.6 算法简介、内部处理与使用范例
    • 19.6.1 算法简介
    • 19.6.2 算法内部一些处理
    • 19.6.3 一些典型算法使用范例
  • 19.7 函数对象回顾、系统函数对象与范例
    • 19.7.1 函数对象/仿函数回顾
    • 19.7.2 标准库中定义的函数对象
    • 19.7.3 标准库中定义的函数对象范例
  • 19.8 适配器概念、分类、范例与总结
    • 19.8.1 适配器基本概念
    • 19.8.2 容器适配器
    • 19.8.3 算法适配器
    • 19.8.4 迭代器适配器
    • 19.8.5 总结

19.1 STL总述、发展史、组成与数据结构谈

19.1.1 几个概念与推荐书籍

  1. C++标准库
    C++ Standard Library,一般安装C++编译器时都会安装。

  2. 标准模板库
    Standard Template Library(STL),包含在C++标准库中(核心)。

  3. 泛型编程
    Generic Programming,使用模板(Template)为主要编程手段来编写代码。

标准模板库就是用泛型编程的编码方式写的一套供程序员非常方便使用的库。

  1. 推荐书籍
    《C++标准库》、《STL源码剖析》。

19.1.2 算法和数据结构谈

  1. 数据结构浅谈
    数据结构,研究数据存取的学问。栈、队列、链表、散列表(哈希表)、树、图等,存取速度快慢,优劣势,具体使用场景等。

  2. 数据结构学习方法
    (1)栈:后进先出。
    (2)队列:先进先出。
    (3)链表:多个节点链(串)在一起,每个节点都有数据部分和next指针部分。
    (4)其它树、图、散列表等。

  3. 推荐书籍
    《算法导论》

19.1.4 标准库使用

#include <iostram>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;

19.1.5 STL的组成部分

  1. 容器
    vetcor、map、list等。

  2. 迭代器
    用于遍历或者访问容器中的元素,类似指针。

  3. 算法(函数)
    STL提供的一些函数,用来实现一些功能,例如search(查找)、sort(排序)、copy(复制)等。

  4. 分配器
    不太常用,针对频繁分配小块内存时,减少内存空间的浪费,具有一定的提升分配内存效率的作用(内存分配器)。一般使用默认分配器(allocator)。

  5. 其它
    适配器、仿函数(函数对象)等。

19.2 容器分类与array、vector容器精解

19.2.1 容器的分类

容器,保存数据,用于管理一大群元素。

  1. 顺序容器
    Sequence Containers,array、vector、deque、queue、stack、list、forward_list。

  2. 关联容器
    Associative Containers,每一个元素都是一个键值(key/value)对。通过键来找元素,类似小数据库或小字典,查找快速。内部使用树的数据结构来存储数据,按照一定规则(比如根据key)自动存放元素位置,无法控制元素插入位置,只能控制插入内容。set、multiset、map、multimap。
    hash_set、hash_multiset、hash_map、hash_multimap等(已过时,用unordered_set、unordered_multiset、unordered_map、unordered_multimap替代)。

  3. 无序容器
    Unordered Contianers,属于关联容器的一种,只在意元素是否在容器内,内部用哈希表实现。
    unordered_set、unordered_multiset、unordered_map、unordered_multimap等。

19.2.2 容器的说明和简单应用

  1. array
    顺序容器,数组,空间连续,大小固定。

与内置数组比较:
(1)比内置数组更安全,内置数组不能直接使用拷贝和赋值,array数组可以。
(2)array下标必须是无符号类型,而数组则没有这个限制(可以负数)。

array<int, 10> ial1={0,1,2,3};
array<int, 10> copy=ial1;//只要保证两者的类型一致就可以(包括元素类型和大小)
#include <array>

array<string, 5> mystring = {"I", "love", "china"};
cout <<mystring.size()<<endl;//5
cout <<sizeof(mystring)<<endl;//不等于5,array<string, 5>类的大小
mystring[0] = "long long long";
  1. vector
    空间连续,动态大小,超过容量时,重新分配空间。
    建议vector内使用指针,或者提前分配空间。
#include <vector>
#include <iostream>
using namespace std;

class A
{
public:
    int m_i;
    A(int tmp = 0) : m_i(tmp)
    {
        cout << "A(int)\n";
    }
    A(const A &a)
    {
        m_i = a.m_i;
        cout << "A(const A&) \n";
    }
    ~A()
    {
        cout << "~A()\n";
    }
};

#define N 3
int main()
{
    {
        //vector<A> veca(N);
        vector<A> veca;
        veca.reverse(N);
        for (int i = 0; i < N; i++)
        {
            cout << "size=" << veca.size() << endl;
            cout << "capacity=" << veca.capacity() << endl;
            // veca.push_back(A(1));//未提前分配空间,会多次调用构造函数和析构函数
            // veca.emplace_back(A(1));//就地在尾部插入类,省去了拷贝或移动元素的过程。
            veca[i] = A(i);
        }
    }
    cout << "over";
    return 0;
}

19.3 容器的说明和简单应用续

19.3.1 deque和stack

  1. deque
    double-ended queue,双端队列(双向开口)。
    分段数组,内存是分段连续的。
#include <iostream>
#include <deque>
using namespace std;

class A
{
public:
    A(int tmp) : m_i(tmp)
    {
        cout << "A(int)" << endl;
    }
    A(const A &tmpA)
    {
        m_i = tmpA.m_i;
        cout << "A(const A&)" << endl;
    }
    ~A()
    {
        cout << "~A()" << endl;
    }

public:
    int m_i;
};

int main()
{
    {
        deque<A> mydeque;
        for (int i = 0; i < 2; i++)
        {
            cout << "begin" << endl;
            mydeque.push_front(A(i));
            mydeque.push_back(A(i));
            cout << "end" << endl;
        }
        for (int i = 0; i < mydeque.size(); i++)
        {
            cout << i << ": " << mydeque[i].m_i << ", address: " << &mydeque[i] << endl;
        }
    }

    cout << "main over" << endl;
    return 0;
}
  1. stack
    栈或堆栈。
    一端开口,后进先出。

19.3.2 queue

队列,先进先出,一端进,一端出。

19.3.3 list

双向链表,内存空间不连续。

沿链查找元素,查找效率不突出;任意位置插入和删除元素都非常迅速。

19.3.4 其它

  1. forward_list
    单向链表,push_front,头部插入数据。无push_back。

  2. map和set
    关联容器,内部实现多为红黑树。
    map容器,每个元素都是键值对(key/value),key不能重复,重复需使用multimap。

#include <iostream>
#include <map>
#include <string>
using namespace std;

class A
{
public:
    int m_i;
    A(int tmp = 0) : m_i(tmp)
    {
        cout << "A(int)\n";
    }
    A(const A &a)
    {
        m_i = a.m_i;
        cout << "A(const A&) \n";
    }
    ~A()
    {
        cout << "~A()\n";
    }
};

#define N 3
int main()
{
    map<int, string> mymap = {
        pair<int, string>(1, "java"),
        pair<int, string>(2, "c++"),
        {3, "python"},
        make_pair(4, "go")};
    cout << mymap[4] << endl;

    mymap.insert({4, "matlab"}); // key,4存在,这行不执行
    cout << mymap.at(4) << endl;

    mymap[4] = "matlab"; // key,4存在,会被替换
    cout << mymap.at(4) << endl;

    mymap[5] = "ruby"; // key,5不存在,会赋值
    cout << mymap.at(5) << endl;

    cout << mymap.size() << endl;
    cout << mymap[6] << endl;     //生成一个{6, ""}
    cout << mymap.size() << endl; //+1

    auto iter = mymap.find(3);
    if (iter != mymap.end())
    {
        cout << iter->first << endl;
        cout << iter->second << endl;
    }

    cout << "over";
    return 0;
}

set容器中,每个元素都是value,value不能重复,重复需使用multiset。

map、set等关联容器,插入速度慢一些(寻找合适位置),查找速度快。

  1. unordered_map、unordered_set等
    unordered_开头容器属于无序容器,内部一般使用哈希表(散列表)实现。
    unordered_map、unordered_set不重复,unordered_multimap、unordered_multiset可重复。
#include <iostream>
#include <unordered_set>
#include <algorithm>
using namespace std;

int main()
{
    unordered_set<int> myset;
    cout << myset.bucket_count() << endl;

    for (int i = 0; i < 8; i++)
        myset.insert(i);
    cout << myset.bucket_count() << endl;

    cout << myset.max_bucket_count() << endl;
    cout << myset.size() << endl;

    for (int i = 0; i < myset.bucket_count(); i++)
        cout << myset.bucket_size(i) << endl;

    if (myset.find(5) != myset.end())
        cout << "find\n";

    if (find(myset.begin(), myset.end(), 5) != myset.end())
        cout << "find\n";

    cout << "over";
    return 0;
}

19.4 分配器简介、使用与工作原理说

19.4.1 分配器简介

vector<int> myvec;
vector<int, std::allocator<int>> myvec;

内存分配器扮演着内存池的角色,大量减少对malloc的调用以减少对内存分配的浪费。

list<int> mylist;
mylist.push_back(10);
mylist.push_back(20);
mylist.push_back(36);
for(auto iter = mylist.begin(); iter != mylist.end(); ++iter){
	cout<<*iter<<endl;
	int *p=&(*iter);
	printf("%p\n", p);
}
//测试表明,默认分配器未使用内存池工作机制,原样调用底层malloc。

19.4.2 分配器的使用

分配器分配内存,写入数据,释放内存。

allocator<int> aalloc;
int *p=aalloc.allocate(3);
int *q=p;
*q=1;q++;
*q=2;q++;
*q=3;
aalloc.deallocate(p, 3);

19.4.3 其它的分配器与原理说

分配器就是一次分配一大块内存,每次使用一小块,用链表将这些内存块管理起来。通过内存池的内存分配机制,有效减少调用malloc次数,减少内存浪费,提高程序运行效率。

//分配器上不同编号对应不同大小的内存块,
//应对不同大小的内存分配申请
//3个list可能共用一个分配器
list<int, allocator<int>> mylist1;
list<double, allocator<double>> mylist2;
list<int, allocator<int>> mylist3;

19.5 迭代器的概念和分类

19.5.1 迭代器基本概念

可遍历STL容器全部或部分元素的对象(行为类似于指针对象,*iter获取迭代器所指向的内容)。
迭代器由容器提供(容器里面定义者迭代器的具体类型细节),用来表现容器中的某一个位置。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> iv = {1, 2, 3};
    for (vector<int>::iterator iter = iv.begin(); iter != iv.end(); ++iter)
    {
        *iter += 6;
        cout << *iter << endl;
    }

    cout << "over";
    return 0;
}

19.5.2 迭代器的分类

依据迭代器的移动特性和操作进行分类。
(1)输出型迭代器(Output iterator)
struct output_iterator_tag
(2)输入型迭代器(Input iterator)
struct input_iterator_tag
(3)前向型迭代器(Input iterator)
struct forward_iterator_tag
(4)双向迭代器(Bidirectional iterator)
struct bidirectional_iterator_tag
(5)随机访问迭代器(Random-access iterator)
struct random_access_iterator_tag

struct output_iterator_tag

继承关系:
struct input_iterator_tag

struct forward_iterator_tag

struct bidirectional_iterator_tag

struct random_access_iterator_tag

多数容器有迭代器,stack、queue等容器不提供迭代器。

迭代器种类迭代器能力提供该迭代器的容器
output_iterator_tag向前写入ostream
input_iterator_tag向前读取一次istream
forward_iterator_tag向前读取forward_list、nordered
bidirectional_iterator_tag向前和向后读取list、set、multiset、map、multimap
random_access_iterator_tag随机读取(跳过一定个数的元素)array、vector、deque、string、C风格数组
#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <map>
#include <set>
using namespace std;

void _display_category(output_iterator_tag mytag)
{
    cout << "output_iterator_tag" << endl;
}
void _display_category(input_iterator_tag mytag)
{
    cout << "input_iterator_tag" << endl;
}
void _display_category(forward_iterator_tag mytag)
{
    cout << "forward_iterator_tag" << endl;
}
void _display_category(bidirectional_iterator_tag mytag)
{
    cout << "bidirectional_iterator_tag" << endl;
}
void _display_category(random_access_iterator_tag mytag)
{
    cout << "random_access_iterator_tag" << endl;
}

template <typename T>
void display_category(T iter)
{
    cout << "begin" << endl;

    typename iterator_traits<T>::iterator_category cagy; //过滤器(萃取机),获取T迭代器类型的种类
    _display_category(cagy);
    cout << "typeid(iter).name()=" << typeid(iter).name() << endl;

    cout << "end" << endl;
}

int main()
{
    display_category(array<int, 100>::iterator()); //()用于产生临时对象
    display_category(vector<int>::iterator());
    display_category(list<int>::iterator());
    display_category(map<int, int>::iterator());
    display_category(set<int>::iterator());

    cout << "over";
    return 0;
}

迭代器功能整理:
(1)输出型迭代器(Output iterator)
struct output_iterator_tag
一步步往前走,通过这个迭代器往容器中写数据。
*iter = value,value写入迭代器指向的位置。
++iter
iter++

(2)输入型迭代器(Input iterator)
struct input_iterator_tag
一步步往前走,通过这个迭代器顺序返回元素值。
*iter,读取元素值
iter->member,读取元素成员
++iter
iter++
iter1 == iter2
iter1 != iter2

(3)前向型迭代器(Input iterator)
struct forward_iterator_tag
继承input_iterator_tag,同时支持写入操作
*iter,读取元素值
iter->member,读取元素成员
*iter = value,value写入迭代器指向的位置。
++iter
iter++
iter1 == iter2
iter1 != iter2
iter1 = iter2,迭代器赋值

(4)双向迭代器(Bidirectional iterator)
struct bidirectional_iterator_tag
继承forward_iterator_tag,增加向回(反向)迭代,即迭代位置可以往回退。
*iter,读取元素值
iter->member,读取元素成员
*iter = value,value写入迭代器指向的位置。
++iter
iter++
iter1 == iter2
iter1 != iter2
–iter
iter–

(5)随机访问迭代器(Random-access iterator)
struct random_access_iterator_tag
继承bidirectional_iterator_tag,增加随机访问能力,即增减偏移量,同时能够计算距离,支持一些关系运算等。
*iter,读取元素值
iter->member,读取元素成员
*iter = value,value写入迭代器指向的位置。
++iter
iter++
iter1 == iter2
iter1 != iter2
–iter
iter–

iter[n]
iter+=n
iter-=n
iter+n
iter-n
iter1-iter2,计算距离
iter1<iter2, iter1>iter2
iter1<=iter2, iter1>=iter2

19.6 算法简介、内部处理与使用范例

19.6.1 算法简介

19.6.2 算法内部一些处理

算法是函数模板,接收各种类型的迭代器作为形参。算法内部根据迭代器类型,有不同处理,处于算法执行效率的考虑。

19.6.3 一些典型算法使用范例

#include <algorithm>
  1. for_each
void func(int i){
	cout<<i<<endl;
}

vector<int> myvector = {10, 20, 30, 40, 50};
//两个形参迭代器,一个可调用对象,
//不断迭代两个迭代器间的元素,作为实参来调用myfunc函数。
for_each(myvector.begin(), myvector.end(), func);
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f){
	for(; first != last; ++first)
		f(*first);
	return f;
}
  1. find
vector<int> myvector = {10, 20, 30, 40, 50};
vector<int>::iterator finditer = find(myvector.begin(), myvector.end(), 400);
if(finditer != myvector.end())
	cout<<"find"<<endl;
else
	cout<<"not find"<<endl;

//优先使用容器自带(若存在)的同名函数。

map<int, string> mymap;
mymap.insert(std::make_pair(1, "wang"));
mymap.insert(std::make_pair(2, "li"));
auto finditer = mymap.find(2);
if(finditer != mymap.end()){
	cout<<"find"<<endl;
	cout<<iter->first<<iter->second<<endl;
}
  1. find_if
vector<int> myvector = {10, 20, 30, 40, 50};
auto finditer = find_if(myvector.begin(), myvector.end(), [](int val){ //可调用对象
	if(val>15)
		return true; //返回第一个满足规则的元素
	return false;
});
if(finditer != myvector.end())
	cout<<"find"<<*finditer<<endl;
else
	cout<<"not find"<<endl;
  1. sort
vector<int> myvector = {10, 20, 30, 40, 50};
//sort(myvector.begin(), myvector.end());//默认升序
sort(myvector.begin(), myvector.begin()+3);//前三个元素升序
bool myfuncsort(int i, int j){
	//return i<j;//升序
	return i>j;//降序
}
sort(myvector.begin(), myvector.end(), myfuncsort);
class A{
public:
	bool operator()(int i, int j){
		//return i<j;//升序
		return i>j;//降序
	}
};

A a;
sort(myvector.begin(), myvector.end(), a);
list<int> mylist = {10, 20, 30, 40, 50};
//sort(mylist .begin(), mylist .end());//sort算法不适用于双向迭代器,只适用于随机访问迭代器
mylist.sort(myfuncsort);//list容器自带sort成员函数

顺序容器可以排序,关联容器(含无序容器)不适合排序。

map<int, string> mymap;
mymap.insert(make_pair(50, "wang"));
mymap.insert(make_pair(15, "li"));
mymap.insert(pair<int, string>(80, "zhao"));
//sort(mymap.begin(), mymap.end());//error
unordered_set<int> myset = {10, 20, 30, 40, 50};
//sort(myset .begin(), myset .end());//error

19.7 函数对象回顾、系统函数对象与范例

19.7.1 函数对象/仿函数回顾

函数对象(function objects)或仿函数(functors),配合算法使用实现特定功能,调用方式很统一,即:名字(参数列表)。
函数对象形式整理

  • 函数:void func(int x) {…}
  • 可调用对象(类/类模板生成对象):class A{public:void operator()(int x){}};
  • lambda表达式:[](int x){};

19.7.2 标准库中定义的函数对象

#include <functional>
  1. 算术运算类
表达式(函数对象)效果
negate<类型>()-param
plus<类型>()param1+param2
minus<类型>()param1-param2
multiplies<类型>()param1*param2
divides<类型>()param1/param2
modulus<类型>()param1%param2
  1. 关系运算类
表达式(函数对象)效果
equal_to<类型>()param1==param2
not_equal_to<类型>()param1!=param2
less<类型>()param1<param2
greater<类型>()param1>param2
less_equal<类型>()param1<=param2
greater_equal<类型>()param1>=param2
  1. 逻辑运算符
表达式(函数对象)效果
logical_not<类型>()!param
logical_and<类型>()param1&&param2
logical_or<类型>()param1||param2
  1. 位运算类
表达式(函数对象)效果
bit_xor<类型>()param1^param2
bit_and<类型>()param1&param2
bit_or<类型>()param1|param2
template<class _Ty = void>
struct plus{
	constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const {
		return _Left + _Right;
	}
};
cout<<plus<int>()(4, 5)<<endl;
//plus<int>实例化类
//plus<int>()临时可调用对象(重载了operator())
//plus<int>()(4, 5)函数调用

19.7.3 标准库中定义的函数对象范例

vector<int> myvector = {10, 20, 30, 40, 50};
sort(myvector.begin(), myvector.end(), greater<int>());
sort(myvector.begin(), myvector.end(), less<int>());
//greater<int>()和less<int>()产生临时的可调用对象

19.8 适配器概念、分类、范例与总结

19.8.1 适配器基本概念

类似于转接头。将一个既有东西进行适当改造,增减一点东西,就会成为一个适配器。

19.8.2 容器适配器

stack和queue归类为容器适配器,将既有的deque进行适当的改造(阉割一点东西)。

template<class _Ty, class _Container = deque<_Ty>>
class queue {
public:
	//...
	void push(value_type && _Val){
		c.push_back(_STD move(_Val));
	}
protected:
	_Container c;
};

19.8.3 算法适配器

算法是函数模板,算法适配器就是函数适配器,最典型的是绑定器(Binder)。
bind,函数模板,算法适配器中的绑定器。

vector<int> myvector = {50, 15, 80, 30, 46, 80};
int cishu = count(myvector.begin(), myvector.end(), 80);
cout << cishu <<endl;
class A{
public:
	bool operator()(int i){
		return i>40;
	}
};

A a;
cishu = count_if(myvector.begin(), myvector.end(), a);
template<class _Ty = void>
struct less{
	constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const {
		return _Left < _Right;
	}
};

class A{
public:
	bool operator()(int i){
		//return i>40;
		return 40<i;
	}
};

//less<int>()中operator()第一个参数绑定了40
auto bf = bind(less<int>(), 40, placeholders::_1);
bf(19);//调用,第二个参数19

cishu = count_if(myvector.begin(), myvector.end(), bind(less<int>(), 40, placeholders::_1));

19.8.4 迭代器适配器

方向迭代器就是一个迭代器适配器。

vector<int> iv = {100, 200, 300};
for(vector<int>::reverse_iterator riter = iv.rbegin(); riter != iv.rend(); riter++)
	cout<<*riter<<endl;

19.8.5 总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《C++新经典》第19章 STL标准模板库大局观 的相关文章

  • 用于列表和映射的 C++ 容器

    我们有一个键和值对的集合 我们需要一个容器 它可以帮助我们检索值 o 1 但也可以记住插入顺序 以便当我们进行迭代时 我们可以像插入顺序一样进行迭代 由于键是一个字符串 我们将无法使用集合或类似的结构 目前我们已经定义了自己的集合类 其中包
  • C++ 中的映射的多个键

    我有一个表 其中的条目是这样的 Row Column1 Column2 Column3 Column4 1 0X0A 1 2 A 2 0X0B 2 2 B 3 0x0C 3 2 C 现在我想使用映射 以便我可以使用第 1 列或第 2 列作为
  • 如何将 std::map 输出到二进制文件?

    我怎样才能输出一个std map到二进制文件 地图声明如下所示 map
  • 迭代 C++ 映射中的键

    有没有办法迭代键 而不是 C 映射对 地图是关联容器 因此 迭代器是一对key val 如果您只需要键 则可以忽略该对中的值部分 for std map
  • 二维向量的迭代器

    如何为 2d 向量 向量的向量 创建迭代器 虽然你的问题是not非常清楚 我假设您的意思是 2D 向量表示向量的向量 vector lt vector
  • 在 C++ 中将惰性生成器实现为forward_iterator

    MyGenerator 表示 可能 有限的整数序列 计算成本很高 所以我不想预先生成它们并将它们放入容器中 struct MyGenerator bool HasNext int Next 要打印全部 MyGenerator generat
  • 如何对多重映射中的键和值进行排序?

    建议使用任何方法对多重映射的键及其值进行排序 例如 输入 5 1 1 9 1 1 5 2 1 2 输出必须是 1 1 1 2 1 9 5 1 5 2 答案是emplace hint 伪代码如下所示 insert with hint M mm
  • Windows Unicode C++ 流输出失败

    我目前正在编写一个应用程序 它要求我在任意窗口上调用 GetWindowText 并将该数据存储到文件中以供以后处理 长话短说 我注意到我的工具在 战地 3 上失败了 我将问题范围缩小到窗口标题中的以下字符 http www filefor
  • STL 映射值构造函数

    我有一个类 X 我想将其放入 std map 类型的 STL 映射中 STL 映射需要将 X 存储在内存中的某个位置 因此我正在寻找一种有效的 运行时和内存 方法来创建 X 并将其存储在映射中 我注意到以下代码 其中 x 是 X 类型的对象
  • 为什么这个 C++ STL 分配器不分配?

    我正在尝试编写一个派生自的自定义 STL 分配器std allocator 但不知何故所有的电话allocate 去基础班 我已将范围缩小到以下代码 template
  • STL迭代器是否保证集合更改后的有效性?

    假设我有某种集合 并且我在它的开头获得了一个迭代器 现在假设我修改了该集合 无论集合或迭代器的类型如何 我仍然可以安全地使用迭代器吗 为了避免混淆 以下是我讨论的操作顺序 获取集合的迭代器 修改集合 显然 不是其中的元素 而是集合本身 使用
  • 从 STL 容器并行读取

    从多个并行线程读取 STL 容器是安全的 然而 表现却很糟糕 为什么 我创建了一个小对象 将一些数据存储在多重集中 这使得构造函数相当昂贵 在我的机器上大约为 5 usecs 我将数十万个小对象存储在一个大型多重集中 处理这些对象是一项独立
  • const_iterator 和 iterator 有什么区别? [复制]

    这个问题在这里已经有答案了 这两者在 STL 内部的实现方面有什么区别 性能方面有什么区别 我想当我们以 只读方式 遍历向量时 我们更喜欢const iterator right 谢谢 没有性能差异 A const iterator是一个指
  • 如何确保 std::map 是有序的?

    Using a std map
  • 为什么 std::set 没有“包含”成员函数?

    我正在大量使用std set
  • 带有自定义分配器的 std::string

    所以我目前正在编写一个内存调试器 为此我需要 stl 容器对象来使用未跟踪的分配器 我的整个代码库中都散布了 std string 因此我将其键入以使用未跟踪的分配器 typedef std basic string
  • std::enable_if 和 std::enable_if_t 有什么区别?

    C 14 引入std enable if t 它和有什么区别std enable if 使用上有什么优点或者区别吗std enable if t std enable if t 是 std enable if 的内部 type 的类型别名
  • 获取 const 引用的迭代器

    我正在开发一个必须返回一个迭代器的类begin 方法 另外 我必须开发一个函数来接收此类的 const 引用并对其进行迭代 当我尝试从此方法获取迭代器时 出现以下编译错误 the object has type qualifiers tha
  • 我应该将哪个 STL 容器用于 FIFO?

    哪种 STL 容器最适合我的需求 我基本上有一个 10 个元素宽的容器 我在其中不断地push back新元素的同时pop front计算最旧的元素 大约一百万次 我目前正在使用std deque对于这项任务 但想知道是否std list会
  • is_integral 与 is_integer:其中之一是多余的吗?

    是积分 http en cppreference com w cpp types is integral and 是整数 http en cppreference com w cpp types numeric limits is inte

随机推荐