成都网站建设顶呱呱,青岛地产网站建设,建筑网站建设方案,隆化县建设局网站新增默认成员函数
C11之前#xff0c;默认成员函数有六个#xff0c;构造函数#xff0c;析构函数#xff0c;拷贝构造#xff0c;拷贝赋值重载#xff0c;取地址重载#xff0c;const 取地址重载。
C11增加了 移动构造 和 移动赋值重载
如果类没有实现移动构造…新增默认成员函数
C11之前默认成员函数有六个构造函数析构函数拷贝构造拷贝赋值重载取地址重载const 取地址重载。
C11增加了 移动构造 和 移动赋值重载
如果类没有实现移动构造且没有实现析构拷贝拷贝赋值重载中的任意一个才会生成默认的移动构造。
默认的移动构造对内置类型进行按字节拷贝自定义类型调用它的移动构造该自定义类型没有实现移动构造就调用拷贝构造。
默认的移动赋值的生成和调用逻辑也类似。
新增关键字
default : 强制生成默认的成员函数
delete 强制禁用默认的成员函数
可变模板参数
C11之后模板可以接受多个参数
// Args是一个模板参数包args是一个函数形参参数包
// 声明一个参数包Args...args这个参数包中可以包含0到任意个模板参数。
template class ...Args
void ShowList(Args... args)
{}
//引用接收万能引用
template class ...Args
void ShowList(Args... args)
{}实现一个打印函数
//递归的出口
void _my_print() { ;
}
//递归解析参数包 (args...)
template class T, class... Args
void _my_print(T x, Args... args) { cout x endl; _my_print(args...);
}
//打印函数可以传入不同类型的参数
template class... Args
void my_print(Args... args) {_my_print(args...);
}调用一下
int main() { my_print(2025,1.1, c, string(C)); return 0;
}结果如下 上述代码是在编译时递归式解析参数包
STL容器的 emplace_back 系列
STL的容器增加了 emplace_back 接口功能和和 push_back 一样。
以 std::vector 为例看一下接口
template class... Args
void emplace_back( Args... args );emplace_back 支持了模板的可变参数假如我用插入一个 pairstring, int 类型的数据emplace_back 只需传入 string 和 int 类型的参数即可无需构造临时的 pairstring, int 对象。
我们分析如下代码来理解一下 vectorpairstring, int v; v.push_back({ 西瓜, 2 }); v.emplace_back(西瓜, 2);首先{ “西瓜”, 2 } 是列表初始化相当于隐式类型转换会调用pair的构造函数来构造出pairstring, int类型的临时对象该临时对象属于右值会调用vector的移动构造转移资源所以
v.push_back({ “西瓜”, 2 }) 插入是pair的构造 vector的移动构造
而 emplace_back 相当于传参给vector的构造vector直接构造pairstring, int类型对象并插入容器中。
v.emplace_back(“西瓜”, 2) 的插入只调用了vector的构造
所以从效率上说对于浅拷贝的类或内置类型emplace_back 效率更高。对于深拷贝的类效率相差不大。
lambda表达式
lambda 表达式是一个匿名函数对象语法如下
[捕捉列表](参数)mutable - 返回值类型 {函数体};lambda 表达式中很多内容可以省略
如下代码
auto func []() {};
func();写一个add函数如下代码
//也可以不带返回值类型 [](int a, int b) { return a b; };
auto add [](int a, int b)-int { return a b;};
cout add(3, 4) endl;捕捉列表可以捕捉当前作用域的变量加 符号表示传引用捕捉不加表示传值捕捉lambda表达式会拷贝一份新的副本
如下代码传值捕捉新的副本具有 const属性
int main() { int a 3, b 4;//lambda表达式中的 a b 是 mian 函数a b 的一份拷贝auto add [a, b]() { return a b; };cout add() endl;取消传值捕捉的 const 属性需要加 mutable 关键字 auto add [a, b]() mutable { return a b; } ;传引用捕捉如下代码 int a 3, b 4;auto add [a, b]() mutable { a; b; };add();cout a b endl;其他的一些捕捉凡是如下可以和上述的捕捉方式混合使用。
[]表示值传递方式捕获所有父作用域(包含lambda函数的语句块)中的变量(包括this)
[]表示引用传递捕捉所有父作用域中的变量(包括this)
[this]表示值传递方式捕捉当前的this指针
function 包装器
function 的本质是类模板用来包装一切可调用对象。
可调用对象包括函数指针仿函数函数名lambda表达式。
// 类模板原型如下
template class T function; // undefined
template class Ret, class... Args
class functionRet(Args...);
//Ret: 被调用函数的返回类型
//Args…被调用函数的形参std::function 的实例化需要指定返回值类型和参数类型
function返回值类型(参数类型...) 对象名 可调用对象;如下示例
int f(int a, int b)
{return a b;
}
std::functionint(int, int) func1 f;
//调用func1
func1(1, 2);function 类模板重载了 () 调用该对象可以和仿函数一样。
对于非静态成员函数可调用对象需要 符号静态成员函数不需要
class op {
public:static int sub(int a, int b) {return a - b;}int sum(int a, int b) {return a b; }
};functionint(op*, int, int) f1 op::sum;
functionint(int, int) f2 op::sub;std::bind
bind 是一个函数模板接受一个可调用对象生成一个新的可调用对象。bind 用来调整参数的顺序和个数。
// 原型如下
template class Fn, class... Args
/* unspecified */ bind (Fn fn, Args... args);
// with return type (2)
template class Ret, class Fn, class... Args
/* unspecified */ bind (Fn fn, Args... args);以上述的 op 类举例绑定成员函数
op p;
functionint(int, int) f3 bind(op::sum, p, placeholders::_1, placeholders::_2);
functionint(int, int) f4 bind(op::sum, p, placeholders::_1, placeholders::_2);placeholders::_n 是占位符不需要绑定的参数用 placeholders::_n 表示。