Hello World

行走即是圆梦,回望亦是前行。

0%

stl标准模板库

前言

这里简单记录下stl标准模板库学习笔记

c++备忘

  • 宏参数#、##、##__VA_ARGS__

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //可变参数宏
    #define MODEL_NAEM "my_test"
    #define printf_log(fmt, ...) printf("[LOGINFO] %s: [%s:%d]" fmt, MODEL_NAEM, __FUNCTION__, __LINE__, ##__VA_ARGS__)

    #define PRINT(fmt, value) printf("the value if " #value " is %d\n", value)
    #define ADD_TO_AN(num, value) a##num += value

    printf_log("%d-%d-%d\n", 2019, 11, 28);

    PRINT("%d", 5);

    int a1 = 1;
    int a2 = 2;
    ADD_TO_AN(1, 4);
    ADD_TO_AN(2, 5);
    printf("%d, %d", a1, a2);
  • 生成指定范围随机数

    1
    2
    3
    4
    #define Random1(low, up)    (rand() % (up - low - 1) + low + 1) //(low, up)
    #define Random2(low, up) (rand() % (up - low) + low) //[low, up)
    #define Random3(low, up) (rand() % (up - low) + low + 1) //(low, up]
    #define Random4(low, up) (rand() % (up - low + 1) + low) //[low, up]
  • 用于std::string的格式化函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static std::string string_format(const char* fmt, ...) {
    std::string strRet;
    if (nullptr != fmt) {
    va_list args = nullptr;
    va_start(args, fmt);

    int nLength = _vsnprintf(nullptr, 0, fmt, args);
    if (nLength > 0) {
    std::unique_ptr<char> uptr(std::make_unique<char>(nLength + 1));
    _vsnprintf(uptr.get(), nLength + 1, fmt, args);
    strRet = uptr.get();
    }
    va_end(args);
    }

    return strRet;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    template<typename T>
    using item_return = T&&;

    template<typename T>
    inline item_return<T> convert(T&& arg) {
    return static_cast<T&&>(arg);
    }

    template<typename... Args>
    std::string string_format(const char* format, Args&&... args) {
    char buff[1024] = { 0 };
    snprintf(buff, sizeof(buff), format, convert(std::forward<Args>(args))...);
    return buff;
    }

    //for test demo
    time_t t = time(NULL);
    struct tm tm = { 0 };
    localtime_s(&tm, &t);
    std::string s = string_format("%d-%d-%d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);

stl (Standard Template Library) 标准模板库 学习笔记
Source Code:

boost: https://www.boost.org/users/download/
sgi_stl: cygnus C++ 2.91 for Windows安装于C:\cygnus,所有头文件置于C:\cygnus\cygwin-b20\include\g++下共128个文件
pj_stl: pj版本被Visual C++采用,所以可以在Visual C++的include子目录下(如: C:\xxx\VC\include)找到所有头文件

容器分类:

  • 顺序容器(元素排序取决于插入顺序)

    vector, deque, list, forward_list, array, string

  • 关联容器(元素排序取决于内部规则)

    set, map, multiset, multimap

  • 无序关联容器

    unordered_set, unordered_map, unordered_multiset, unordered_multimap

  • 容器适配器(可自定义底层数据结构)

    stack, queue, priority_queue(优先级队列)

容器迭代器:

  • 随机访问迭代器

    vector, deque, array

  • 双向迭代器

    list, set, map, multiset, multimap, unordered_set, unordered_map, unordered_multiset, unordered_multimap

  • 前向迭代器

    forward_list

  • 无迭代器

    stack, queue, priority_queue

vector向量

头文件:#include <vector>
特性:

  1. 常用作数组的替代品
  2. 允许尾部直接插入删除
  3. 允许下标随机访问
  4. 常用的内部实现是动态数组

常用操作:

1
2
3
4
5
6
7
8
9
10
std::vector<T> v;
下标访问 v[i]
取长度 v.size()
重置大小 v.resize(x)
尾部插入 v.push_back(x)
尾部删除 v.pop_back()
任意位置插入 v.insert(v.begin()+i, x) //后面的元素后移
任意位置删除 v.erase(v.begin()+i) //后面的元素前移
遍历(可以迭代器方式,但是下标方式更简单)
for(int i = 0; i < v.size(); ++i)

list链表

头文件:#include <list>
特性:

  1. 允许头部/尾部的直接插入/删除
  2. 不允许下标访问
  3. 常用的内部实现是双向链表

常用操作:

1
2
3
4
5
6
7
8
9
10
11
std::list<T> l;
取长度 l.size()
尾部插入 l.push_back(x)
尾部删除 l.pop_back()
头部插入 l.push_front(x)
头部删除 l.pop_front()
特定位置插入 itor=l.insert(itor, x)
特定位置删除 itor=l.erase(itor)
排序 l.sort()
清空 l.clear()
遍历 for(auto itor = l.begin(); itor != l.end(); ++itor)

tuple元组

头文件:#include <tuple>
特性:

  1. c++11 新增
  2. 捆绑N个类型的数据
  3. 常用std::make_tuple构造
  4. 可用于函数返回多个结果

常用操作:

1
2
3
4
auto t = std::make_tuple(a, b, c);
取第N个数据 auto a = std::get<N>(t);
解包 std::tie(a, b, c) = t;
函数多返回值 std::tie(a, b, c) = f(); //f return tuple

示例:

1
2
3
4
5
int a = 0;
std::string str;

std::pair<int, std::string> p = make_pair(123, "abc");
std::tie(a, str) = p;
1
2
3
4
5
6
int a = 0;
char c = '';
std::string str;

std::tuple<int, char, std::string> t = make_tuple(123, 'x', "aaa");
std::tie(a, c, str) = t;

小技巧

加括号避免与宏定义冲突

  1. 常用的最小/最大运算(max/min):
  2. 头文件:#include <algorithm>

方法1:

1
2
3
4
int x = 100;
int y = 200;
int min = (std::min)(x, y);
int max = (std::max)(x, y);

方法2:(该方法必须事先知道,x和y的类型,且二者类型一致)

1
2
3
4
int x = 100;
int y = 200;
int min = std::min<int>(x, y);
int max = std::max<int>(x, y);