accumulate
accumlate将第三个参数作为求和起点,这蕴含一个变成假定:该类型必须支持+操作,也就是定义了+运算符。
std::vector<char> v{'a','b','c','d'};
std::string sum=accumulate(v.cbegin(),v.cend(),string(""));//abcd
如果我们使用char作为第三个参数,那么会报错
std::string sum=accumulate(v.cbegin(),v.cend(),"");
//传递了一个字符串字面量,这个字面量的类型是const char*,它没有定义+运算符
equal
用于确定两个序列是否保存相同的值。它将第一个序列中的每个元素与第二个序列中的对应元素进行比较。equal不仅适用于顺序容器也能适用于关联容器,虽然关联容器中没有顺序,但是它依然能进行比较。
equal(list1.cbegin(),list1.cend(),list2.cbgin());
fill和fill_n
fill接受一对迭代器表示一个范围,同时还接受一个值作为第三个参数,将给定的这个值赋予输入序列中的每个元素。
vector<int> vec;
fill(vec.begin(),vec.end(),0);
fill_n接受一个迭代器指出一个单独的目的位置,从该序列指向的元素开始,填充指定个元素。函数fill_n写入指定个元素是不安全的,比如你不能向一个空的容器中写入多个元素。
vector<int> vec;
fill_n(vec.begin(),vec.size(),0);
fill_n(vec.begin(),10,0);//报错
copy
copy可以向一个目的位置迭代器指出的输出序列中的元素写入数据。
//数组也能算作一种容器,可以使用迭代器,和一些算法
int a1[]={0,1,2,3,4,5,6,7,8,9};
int a2[sizeof(a1)/sizeof(*a1)];
//返回一个指向a2尾元素后位置的迭代器
auto ret=copy(begin(a1),end(a1),a2);
replace和replace_copy
接受一个序列,并将器中所有等于给定值的元素都改为另一个值。此算法接受4个参数:前两个是一对迭代器,第三个是要搜索的值,第四个是新值。
replace(list.begin(),list.end(),0,42);
如果我们希望原序列不变可以使用replace_copy此算法接受第三个迭代器参数,指出调整后序列的保存位置:
replace_copy(list.cbegin(),list.cend(),back_inserter(ivec),0,42);
unique
unique可以使容器中的元素不重复,并返回一个指向不重复值范围末尾的迭代器,这一过程并未改变容器(改变容器大小,元素的值),仅仅使不重复的元素出现在序列开始部分,unique返回的迭代器指示向后的那些元素对用户是透明的。
原来的容器:|a|b|b|c|c|c|c|c|c|c|
修改之后的容器:|a|b|c|*|*|*|*|*|*|*|
⬆返回的迭代器位置
erase
erase 方法用于从容器中移除元素。
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.erase(vec.begin() + 2);//移除单个元素
vec.erase(vec.begin() + 1, vec.begin() + 3);//移除整个
sort
std::sort 是一个非常强大且常用的算法,它位于 头文件中。这个函数用于对容器中的元素进行排序,默认情况下按升序排列。它是基于快速排序、堆排序或其他高效排序算法的实现,具体取决于编译器和执行环境,确保具有很好的平均性能(通常是 𝑂(𝑛log𝑛)复杂度)。
std::vector<int> v = {4, 1, 3, 9, 7};
std::sort(v.begin(), v.end());
如果你需要按降序或根据自定义规则排序,可以提供一个比较函数或 lambda 表达式。
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
bind
std::bind 是 cpp11 标准库中的一个函数适配器,它允许你将一个函数或函数对象与一些参数绑定在一起,从而创建一个新的可调用对象。这个新对象可以像普通函数一样被调用,但部分参数已经被固定。在成员函数的情况下,第一个参数通常是一个对象实例(通过指针或引用)。如果成员函数接受额外的参数,则这些参数将跟随对象实例参数。
#include <functional> // std::bind
auto boundFunc = std::bind(Callable, Arg1, Arg2, ...);
在 std::bind 中使用占位符 std::placeholders::_1, std::placeholders::_2, 等,来指定函数调用时的位置参数。未绑定的参数将在实际调用时传递。使用这一特性可以改变函数参数的位置,比如:
void func(int i,int j){
...
}
auto func2=bind(func,std::placeholders::_2,std::placeholders::_1);//相当于func的两个参数互换位置
std::bind 会将绑定的参数拷贝到内部存储中,这就意味着如果绑定的参数类型无法拷贝(例如,拷贝构造函数被删除的类),std::bind 将无法正常工作。在这种情况下,你需要使用 std::reference_wrapper 来处理这些特殊情况。
#include <iostream>
#include <functional> // std::bind, std::ref
class NonCopyable {
public:
NonCopyable(int value) : value_(value) {}
NonCopyable(const NonCopyable&) = delete; // 禁用拷贝构造函数
void printValue() const {
std::cout << "Value: " << value_ << std::endl;
}
private:
int value_;
};
int main() {
NonCopyable obj(10);
// 使用 std::ref 绑定 obj 的引用
auto boundFunc = std::bind(&NonCopyable::printValue, std::ref(obj));
// 调用绑定后的函数
boundFunc(); // 输出: Value: 10
return 0;
}
std::ref 是 cpp11 标准库中的一个工具函数,它用于创建一个 std::reference_wrapper 对象,以便在需要引用的情况下传递对象。std::reference_wrapper 是一个轻量级的封装类,它可以保存对一个对象的引用,而不是对象的副本。
std::reference_wrapper 是一个模板类,它用于封装对对象的引用,提供了与普通引用类似的接口:
#include <iostream>
#include <functional> // std::reference_wrapper
int main() {
int a = 5;
std::reference_wrapper<int> ref = std::ref(a);
std::cout << "Original value: " << ref.get() << std::endl; // 输出: Original value: 5
ref.get() = 10; // 修改引用的值
std::cout << "Modified value: " << a << std::endl; // 输出: Modified value: 10
return 0;
}