C++ Primer笔记——默认移动操作、移动迭代器、左右值引用成员函数、标准库仿函数、function包装器

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

一.P476 合成的移动操作

二.P480 移动迭代器

三.P483 右值和左值引用成员函数

四.P510 标准库定义的仿函数

五.P512 标准库function类型(包装器


一.P476 合成的移动操作

什么时候会有默认的移动构造和移动赋值函数需满足以下几点

①没有定义任何自己的拷贝控制成员

②类中非静态成员可以移动如果成员是类类型那该成员要有定义的移动操作。

在没有显式定义移动构造情况下什么时候类的移动构造将被定义成删除?(移动赋值同理

①类成员有拷贝构造且未定义移动构造

②类成员没有定义拷贝构造但编译器没有生成默认移动构造

③类成员的移动构造或移动赋值被定义成删除或不可访问

④类析构函数被定义成删除或不可访问

⑤类成员中有const或引用类型

二.P480 移动迭代器

所谓移动迭代器就是解引用该迭代器后得到的是一个右值引用。

C++11定义了一种移动迭代器适配器make_move_iterator()。通过传递给它普通迭代器返回一个移动迭代器。

使用方式如下

vector<int> arr = { 1, 2, 3 ,4 };
auto it = make_move_iterator(arr.begin());

使用场景上一般用于uninitialized_copy函数可以通过传递移动迭代器使用移动构造函数来构造元素。

vector<int> arr = { 1, 2, 3 ,4 };
int* tmp = new int[64];
uninitialized_copy(make_move_iterator(arr.begin()), make_move_iterator(arr.end()), tmp);

需要注意的是在使用移动迭代器时需要确定后续不会再使用该迭代器因为不能保证函数内部不会修改移动迭代器内右值元素。

三.P483 右值和左值引用成员函数

创建成员函数时可以在参数列表后添加引用限定符来规定该函数只能由左值还是右值调用。

如果成员函数只能由左值对象调用那么限定符为&即this指针只能指向左值。

如果成员函数只能由右值对象调用那么限定符为&&即this指针只能指向右值。

举个例子

class T {
public:
	void func()& //左值引用成员函数
	{
		cout << "左值" << endl;
	}
	void func()&& //重载右值引用成员函数
	{
		cout << "右值" << endl;
	}
};

T getRightVal() { //返回右值的函数
	return T();
}

int main(void)
{
	T a;
	a.func();
	getRightVal().func();
	return 0;
}

四.P510 标准库定义的仿函数

标准库定义了一些类重载了小括号可以在泛型算法中用于替换函数类型参数即仿函数。

求和plus<Type>  

内部实现

T operator() (const T& x, const T& y) const {return x+y;}

示例(其他仿函数类似不再演示
transform(first, first + 5, second, results, std::plus<int>());

//将first开始5个元素与second的5个元素相加结果写入results数组中

求差值minus<Type> 

内部实现

T operator() (const T& x, const T& y) const {return x-y;}

求积multiplies<Type> 

内部实现

T operator() (const T& x, const T& y) const {return x*y;}

求差divides<Type> 

内部实现

T operator() (const T& x, const T& y) const {return x/y;}

求余modulus<Type> 

内部实现

 T operator() (const T& x, const T& y) const {return x%y;}

求相反数negate<Type> 

内部实现

T operator() (const T& x) const {return -x;}

判断是否相等equal_to<Type>  //是true否false下同

内部实现

bool operator() (const T& x, const T& y) const {return x==y;}

判断是否不等not_equal_to<Type>

内部实现

bool operator() (const T& x, const T& y) const {return x!=y;}

判断是否大于greater<Type>

内部实现

bool operator() (const T& x, const T& y) const {return x>y;}

判断是否大于等于greater_equal<Type>

内部实现

bool operator() (const T& x, const T& y) const {return x>=y;}

判断是否小于less<Type>

内部实现

bool operator() (const T& x, const T& y) const {return x<y;}

判断是否小于等于less_equal<Type>

内部实现

bool operator() (const T& x, const T& y) const {return x<=y;}

求逻辑与logical_and<Type>

内部实现

 bool operator() (const T& x, const T& y) const {return x&&y;}

求逻辑或logical_or<Type>

内部实现

 bool operator() (const T& x, const T& y) const {return x||y;}

求逻辑非logical_not<Type>

内部实现

 bool operator() (const T& x, const T& y) const {return !x;}

五.P512 标准库function类型(包装器

当使用函数类型作为参数时如果传入的对象是lambda表达式将无法确定具体的类型也就无法指定函数类型传递lambda对象。

对此C++可以使用function模板解决这个问题

function<函数类型>  //可以用这个function类型表示任意一种同函数类型的调用形式

function<int(string)>  等价于

int func(string){};    //普通函数

int operator()(string){};    //仿函数的小括号重载

[](string)->int{};    //lambda表达式

示例如下

可以同时传函数、仿函数、lambda表达式

//以下这些函数中i无实际作用仅作为函数参数来演示
class T {
public:
    //仿函数
	void operator()(int i) {
		cout << "FuncT()" << endl;
	}
};

//函数
void Func(int i) {
	cout << "Func" << endl;
}

//参数为函数类型使用function来测试仿函数、函数、lambda
void test(function<void(int)> f) {
	int i = 10;
	f(i);
}

int main(void)
{
	T a;
	test(a);//传仿函数
	test(Func);//传函数
	test([](int i) {cout << "Lambda" << endl; });//传lambda表达式
	return 0;
}

 


如有错误敬请斧正

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++

“C++ Primer笔记——默认移动操作、移动迭代器、左右值引用成员函数、标准库仿函数、function包装器” 的相关文章