C++ STL 适配器(Adapters)详解

适配器是STL中修改组件接口的强大工具,提供不同的数据结构和功能视图

什么是适配器?

适配器是修改其他组件接口的组件,使它们具有不同的行为或功能。STL提供了三种主要类型的适配器:容器适配器、迭代器适配器和函数适配器。

适配器基本概念
#include <stack>
#include <vector>

int main() {
    // 容器适配器:基于vector实现stack
    std::stack<int, std::vector<int>> myStack;
    
    // 迭代器适配器:反向迭代器
    std::vector<int> vec = {1, 2, 3};
    for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
        // 使用反向迭代器
    }
    
    // 函数适配器:绑定器
    auto is_greater_than_5 = std::bind(std::greater<int>(), 
                                      std::placeholders::_1, 5);
    bool result = is_greater_than_5(10); // true
    
    return 0;
}

容器适配器

容器适配器为顺序容器提供不同的接口

stack

后进先出(LIFO)数据结构

  • push() - 向栈顶添加元素
  • pop() - 移除栈顶元素
  • top() - 访问栈顶元素
  • empty() - 检查栈是否为空
  • size() - 返回元素数量

queue

先进先出(FIFO)数据结构

  • push() - 向队尾添加元素
  • pop() - 移除队首元素
  • front() - 访问队首元素
  • back() - 访问队尾元素
  • empty() - 检查队列是否为空

priority_queue

元素按优先级排序的队列

  • push() - 插入元素
  • pop() - 移除顶部元素
  • top() - 访问顶部元素
  • empty() - 检查是否为空
  • size() - 返回元素数量
容器适配器使用示例
#include <iostream>
#include <stack>
#include <queue>

int main() {
    // stack示例
    std::stack<int> s;
    s.push(10);
    s.push(20);
    s.push(30);
    std::cout << "Stack top: " << s.top() << std::endl; // 30
    s.pop();
    std::cout << "After pop: " << s.top() << std::endl; // 20
    
    // queue示例
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);
    std::cout << "Queue front: " << q.front() << std::endl; // 10
    q.pop();
    std::cout << "After pop: " << q.front() << std::endl; // 20
    
    // priority_queue示例
    std::priority_queue<int> pq;
    pq.push(30);
    pq.push(10);
    pq.push(20);
    std::cout << "Priority queue top: " << pq.top() << std::endl; // 30
    pq.pop();
    std::cout << "After pop: " << pq.top() << std::endl; // 20
    
    return 0;
}

迭代器适配器

提供不同的迭代器访问方式

反向迭代器

rbegin(), rend() - 反向遍历容器

std::vector<int> v = {1,2,3};
for (auto it = v.rbegin(); it != v.rend(); ++it) {
    std::cout << *it << " "; // 3 2 1
}

插入迭代器

back_inserter, front_inserter, inserter

std::vector<int> v;
std::fill_n(std::back_inserter(v), 3, 10);
// v = {10, 10, 10}

流迭代器

istream_iterator, ostream_iterator

std::vector<int> data;
std::copy(std::istream_iterator<int>(std::cin),
          std::istream_iterator<int>(),
          std::back_inserter(data));

函数适配器

修改或组合函数对象的行为

绑定器

bind1st, bind2nd (C++11后被std::bind替代)

auto greater_than_5 = 
    std::bind(std::greater<int>(), std::placeholders::_1, 5);
bool result = greater_than_5(10); // true

否定器

not1, not2 - 对谓词结果取反

auto not_even = std::not1(std::ptr_fun([](int n){ 
    return n % 2 == 0; 
}));
bool result = not_even(3); // true

成员函数适配器

mem_fun, mem_fun_ref - 调用成员函数

struct Person {
    void print() const { /*...*/ }
};
std::vector<Person> people;
std::for_each(people.begin(), people.end(),
              std::mem_fun_ref(&Person::print));

综合示例

使用多种适配器解决实际问题

适配器综合应用
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>

int main() {
    std::vector<int> data = {7, 3, 9, 4, 6, 1};
    
    // 使用反向迭代器输出原始数据(逆序)
    std::cout << "原始数据(逆序): ";
    std::copy(data.rbegin(), data.rend(), 
             std::ostream_iterator<int>(std::cout, " "));
    
    // 使用函数适配器找出所有大于5的数
    auto greater_than_5 = [](int x) { return x > 5; };
    int count = std::count_if(data.begin(), data.end(), greater_than_5);
    std::cout << "\n大于5的元素数量: " << count;
    
    // 使用插入迭代器创建新容器
    std::vector<int> filtered;
    std::copy_if(data.begin(), data.end(), 
                std::back_inserter(filtered), greater_than_5);
    
    // 使用容器适配器(栈)处理过滤后的数据
    std::stack<int> s;
    for (int n : filtered) s.push(n);
    
    std::cout << "\n栈内容: ";
    while (!s.empty()) {
        std::cout << s.top() << " ";
        s.pop();
    }
    
    return 0;
}

输出结果

原始数据(逆序): 1 6 4 9 3 7 
大于5的元素数量: 3
栈内容: 9 7 6