template <class...Args> void Func(Args...args) {} template <class...Args> void Func(Args&...args) {} template <class...Args> void Func(Args&&...args) {}
对于⼀个参数包,我们除了能计算他的参数个数,我们能做的唯一的事情就是扩展它,当扩展⼀个 包时,我们还要提供用于每个扩展元素的模式,扩展⼀个包就是将它分解为构成的元素,对每个元素应用模式,获得扩展后的列表。我们通过在模式的右边放⼀个省略号(...)来触发扩展操作。
void showlist() { cout << endl; } template <class T,class...Args> void showlist(T x, Args...args) { cout << x << " "; showlist(args...); } template <class...Args> void print(Args...args) { //args是N个参数的参数包 //调用showlist,参数包的第一个传给x //剩下N-1个传给第二个参数 showlist(args...); } int main() { print(1, string("xxxxxx"), 2.2); return 0; }
template <class...Args> void emplace_back (Args&&... args);
class Person { public: Person(const char* name="张三", int age=1) :_name(name) ,_age(age) {} private: string _name; int _age; }; int main() { Person s1; Person s2 = s1; Person s3 = move(s1); return 0; }

s2调用默认拷贝构造。s3调用移动构造函数,对于string类型,内部实现了移动构造,就嗲用地洞构造。对于int内置类型,逐字节拷贝。
default关键字:
作用: 显式要求编译器生成某个特殊成员函数的默认实现。 适用于:默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符。
使用场景: 当类中定义了其他构造函数时,编译器可能不再自动生成默认构造函数。用default显式恢复:
class MyClass { public: MyClass(int x) {} // 自定义构造函数 MyClass() = default; // 显式生成默认构造函数 };
delete关键字
作用 显式禁用某个函数(包括成员函数和普通函数),阻止其被调用。
使用场景:
1,禁止拷贝语义 禁用拷贝构造函数和拷贝赋值运算符,常见于资源管理类(如独占资源):
class NonCopyable { public: NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; // 禁用拷贝构造 NonCopyable& operator=(const NonCopyable&) = delete; // 禁用拷贝赋值 };
2,禁用隐式类型转换 删除特定参数类型的重载函数,避免意外的隐式转换:
class MyClass { public: void Process(int x) {} void Process(double) = delete; // 禁止double参数调用 }; MyClass obj; obj.Process(10); // OK obj.Process(3.14); // 编译错误:函数已删除
3,禁用不希望的函数 例如,禁止通过某些方式构造对象:
class Singleton { public: Singleton() = default; Singleton(const Singleton&) = delete; // 禁止拷贝 };
对比传统的实现方式:
1,default vs 隐式生成
2,delete vs 私有化函数(C++11前)
private且不实现,但错误在链接阶段才暴露。
delete在编译阶段直接报错,提供更清晰的错误信息。
final的作用:
class FinalClass final { // 类的内容 };
class Base { public: virtual void show() final { std::cout << "Base show" << std::endl; } }; class Derived : public Base { public: void show() override { // 错误:Base::show是final的 std::cout << "Derived show" << std::endl; } };
override是一个成员函数的修饰符,用于显式地表示一个成员函数覆盖了基类中的虚函数。它主要用于方法重写。
class Base { public: virtual void show() { std::cout << "Base show" << std::endl; } }; class Derived : public Base { public: void show() override { // 显式声明覆盖 std::cout << "Derived show" << std::endl; } };
作用:
override可以显式地声明这种覆盖关系,增强代码的可读性和安全性。
override,但实际并没有覆盖基类中的虚函数(例如,方法签名不匹配),编译器会报错。
unordered_map和unordered_set的加入。右值引用和移动语义相关的push/insert/emplace系列 接口和移动构造和移动赋值,还有initializer_list版本的构造 等。
容器的范围for遍历
std::vector<int> vec = {1, 2, 3}; for (auto& num : vec) { std::cout << num << " "; }
示例:
auto add1 = [](int x, int y)->int {return x + y; }; auto func1 = [] { cout << "hello world" << endl; return 0; }; auto swap1 = [](int& x, int& y) { int tmp = x; x = y; y = tmp; }; //sort的第三个参数可以传lambda表达式的比较函数 std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; // Sort in descending order });
int a = 0, b = 1, c = 2, d = 3; //显示传值和传引用捕捉 auto func1 = [a, &b] { //值捕捉的变量不可以修改 //引用捕捉的变量可以修改 //a++; 报错 b++; int ret = a + b; return ret; }; cout << func1() << endl; //传值捕捉本质是一种拷贝,并且被const修饰了,不能修改 //mutable相当于去掉了const属性,可以修改了 //但是内部修改不会影响外部的值,因为是一种拷贝 auto func = [=]()mutable { a++; b++; c++; d++; return a + b + c + d; }; cout << func() << endl;
//隐式值捕捉 //用了那些变量就捕捉那些变量 auto func2 = [=] { int ret = a + b + c; return ret; }; cout << func2() << endl; //隐式引用捕捉 //用了那些变量就捕捉那些变量 auto func3 = [&] { a++; b++; c++; }; func3(); cout << a << " " << b << " " << c << " " << endl;
//混合捕捉 auto func4 = [&, a, b] { //a++ 报错 //b++ 报错 c++; d++; return a + b + c + d; }; func4(); cout << a << " " << b << " " << c << " " << endl; //混合捕捉 auto func5 = [=, &a, &b] { a++; b++; //c++ 报错 //d++ 报错 }; func5();
//局部的静态和全局变量不能捕捉,不需要捕捉就可以用 static int m = 1; static int n = 2; auto func6 = [ ] { return m + n; };

#include <functional> #include <iostream> int add(int a, int b) { return a + b; } struct Functor { int operator()(int a, int b) { return a + b; } }; int main() { std::function<int(int, int)> f1 = add; // 包装普通函数 std::function<int(int, int)> f2 = Functor(); // 包装仿函数 std::function<int(int, int)> f3 = [](int a, int b) { return a + b; }; // 包装Lambda表达式 std::cout << f1(1, 2) << std::endl; // 输出3 std::cout << f2(1, 2) << std::endl; // 输出3 std::cout << f3(1, 2) << std::endl; // 输出3 }
包装成员函数
class Plus { public: Plus(int n=1) :_n(n) {} static int plusi(int a, int b) { return a + b; } double plusd(double x, double y) { return (x + y) * 10; } private: int _n; }; int main() { //包装静态成员函数 需要指明类域+& function<int(int, int)> f1 = &Plus::plusi; //包装非静态成员函数 需要指明类域+& //非静态成员函数包含this指针 function<double(Plus*, double, double)> f2 = &Plus::plusd; Plus pl; cout << f2(&pl, 1.1, 2.2) << endl; //下面的写法也可以 function<double(Plus, double, double)> f3 = &Plus::plusd; function<double(Plus&, double, double)> f4 = &Plus::plusd; return 0; }


总结:std::bind 是一个绑定器,用于将函数或可调用对象的参数绑定到特定的值上,从而创建一个新的可调用对象。它通常用于固定某些参数,使函数或可调用对象的调用更简单。
调整参数顺序示例:
using placeholders::_1; using placeholders::_2; using placeholders::_3; int sub(int a, int b) { return (a - b) * 10; } int main() { auto sub1 = bind(sub, _1, _2); cout << sub1(10, 5) << endl; auto sub2 = bind(sub, _2, _1); cout << sub2(10, 5) << endl; return 0; }

调整参数个数示例:
int subx(int a, int b, int c) { return (a - b - c) * 10; } //绑死一些参数,达到修改参数个数的目的 //分别绑死第1,2,3个参数 auto sub3 = bind(subx, 100, _1, _2); //a被绑死=100 cout << sub3(5, 1) << endl; auto sub4 = bind(subx, _1, 100, _2); cout << sub4(5, 1) << endl; auto sub5 = bind(subx, _1, _2,100); cout << sub5(5, 1) << endl;

在function部分,在包装一个类的非静态成员函数时,参数必须要传一个对象或者对象的地址,我们可以使用bind来绑定这个参数。
using placeholders::_1; using placeholders::_2; using placeholders::_3; class Plus { public: Plus(int n=1) :_n(n) {} static int plusi(int a, int b) { return a + b; } double plusd(double x, double y) { return (x + y) * 10; } private: int _n; }; int main() { //包装静态成员函数 需要指明类域+& function<int(int, int)> f1 = Plus::plusi; //包装非静态成员函数 需要指明类域+& //非静态成员函数包含this指针 function<double(Plus*, double, double)> f2 = &Plus::plusd; Plus pl; cout << f2(&pl, 1.1, 2.2) << endl; //绑定Plus()参数,传参时就不需要传了 function<double(double, double)> f3 = bind(&Plus::plusd, Plus(), _1, _2); cout << f3(1.1, 2.2) << endl; return 0; }
C++11中的一个重要内容:智能指针,在一篇中更新。