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

目录

一.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;
}

 


如有错误,敬请斧正

猜你喜欢

转载自blog.csdn.net/weixin_61857742/article/details/128644758