Open bosthhe1 opened 1 year ago
包装器是为了防止模板实例化出多份而设计的,具体底层原理不太清楚 没有包装器,模板被实例化出三份
double f1(double x)
{
return x / 2;
}
struct f2
{
double operator()(double x)
{
return x / 3;
}
};
auto f3 = [](double x){return x / 4; };
template<class F,class T>
void func(F f, T x)
{
static int a = 1;
cout << &a << endl;
f(x);
}
int main()
{
func(f1, 1.1);
func(f2(), 1.1);
func(f3, 1.1);
return 0;
}
有包装器模板就只实例化出一份
double f1(double x)
{
return x / 2;
}
struct f2
{
double operator()(double x)
{
return x / 3;
}
};
auto f3 = [](double x){return x / 4; };
template<class F,class T>
void func(F f, T x)
{
static int a = 1;
cout << &a << endl;
f(x);
}
int main()
{
function<double(double)> func1 = f1;
func(func1, 1.1);
function<double(double)> func2 = f2();
func(func2,1.1);
function<double(double)> func3 = f3;
func(func3, 1.1);
return 0;
}
bind是搭配function使用的,bind的可以调换参数传递顺序,在调用成员函数的时候,也可以一劳永逸的传递匿名对象 bind的写法
int func5(int a, int b)
{
return a - b;
}
int main()
{
function<int(int, int)> f1 = bind(func5, placeholders::_1, placeholders::_2);//这里面的_1,_2就是传参顺序,如果将顺序颠倒,那么传参也会颠倒。
cout << f1(1, 2) << endl;;
function<int(int, int)> f2 = bind(func5, placeholders::_2, placeholders::_1);//这里颠倒1,2
cout << f2(1, 2) << endl;
}
class F
{
public:
int func1(int a, int b)
{
return a - b;
}
static int func2(int a, int b)
{
return a - b;
}
};
int main()
{
function<int(int, int)> f1 = bind(&F::func1,F(), placeholders::_1, placeholders::_2);
cout << f1(1, 2) << endl;
function<int(int, int)> f2 = bind(&F::func2, placeholders::_1, placeholders::_2);
cout << f2(1, 2) << endl;
return 0;
}
thread:初始化 传一个方法
int main()
{
mutex mtx;
int x = 0;
thread pt1([&]{//直接使用lambda表达式来使用,记得上锁
mtx.lock();
for (int i = 0; i < 1000000; i++)
{
x++;
}
mtx.unlock();
});
thread pt2([&]{
mtx.lock();
for (int i = 0; i < 1000000; i++)
{
x++;
}
mtx.unlock();
});
pt1.join();
pt2.join();
cout << x << endl;
return 0;
}
传两个参数
#include<thread>
#include<mutex>
int x = 0;
mutex mtx;
void func1(int n)
{
mtx.lock();//这里封装到外面为串行,不能体现出并行,但是在这个场景下,锁在外面既安全,又能提高效率,
//如果锁写在for循环里面,会造成频繁切换恢复上下文,造成效率低下的问题
for (int i = 0; i < n; i++)
{
x++;
}
mtx.unlock();
}
int main()
{
thread pt1(func1, 1000000);
thread pt2(func1, 1000000);
pt1.join();
pt2.join();
cout << x << endl;
return 0;
}
c++11中对于一些简单的++或者--都有一个类进行封装,将其变为原子性的
#include<thread>
#include<atomic>
atomic<int> x = 0;//atomic<int>封装过的x的一些简单操作变为原子性的
void func1(int n)
{
for (int i = 0; i < n; i++)
{
x++;//由于封装过的x++为原子性,所以不用上锁
}
}
int main()
{
thread pt1(func1,10000000);
thread pt2(func1, 10000000);
pt1.join();
pt2.join();
cout << x << endl;
return 0;
}
在线程引用传参的时候,必须使用ref函数传参,如果不调用ref函数传参,对于内置类型和自定义类型会调用传值传参的方式进行传参,不会报错,但是对于mtx传参,会报错 我们发现对于ref传参的b地址一样,但是对于没有ref传参的a,地址不一样
包装器的书写新式 对于普通函数,仿函数的包装是这样的: 对于类成员函数的包装
1.非静态成员函数
2.静态成员函数