【几种可调动对象,Function和bind;线程的调动方式举例】

1.可调动对象的调动方式

方法 1、函数指针调动
方法2 、类类型的括号的重载 调动可调动对象

#include<iostream>
#include<functional>
using namespace std;
struct Foo
{
    void operator()(int x)
    {
        cout<<"Foo operator "<<x<<endl;
    }
};
struct Bar
{
    using Pfun =void (*) (int);Pfun成为一个类型
    static void func(int x)
    {
        cout<<"Bar func"<<x<<endl;
    }
    operator Pfun()const
    {
        return &Bar::func;
    }
};
struct Test
{
public:
    int x_;
    Test(int x):x_(x){

    }
public:
    void funb(){
            cout<<" Test funb"<<x_<<" ";
    }
    int func(int x)
    {
        x_= x;
        cout<<"Test func"<<x<<" ";
    }
};
int add(int x,int y)
{
    return x+y;
}
int main()
{
    int x=10;
    int *p = &x;
    方法调动1:通过函数指针
    void (*fp)(int) = Bar::func; 
    fp(x);
    方法调动2:通过对象重载
    Foo foo;  
    foo(x);方法调动2:重载实现调动
    Bar bar;
    return 0;
}

打印结果:

Bar func10
Foo operator 10


方法3、function

struct Test
{
public:
    int x_;
    Test(int x):x_(x){

    }
public:
    void funb(){
            cout<<" Test funb"<<x_<<" ";
    }
    int func(int x)
    {
        x_= x;
        cout<<"Test func"<<x<<" ";
        return x;
    }
};
int add(int x,int y)
{
    return x+y;
}
int main()
{
    std::function<int(int,int)>pfuna = add;
    auto val = pfuna(1,2);
    int x=10;
    Test test(10);  
    std::function<void(Test&)>pfunb =&Test::funb;
    pfunb(test);
    std::function<int(Test&,int )>pfunc = &Test::func;
    auto val1 = pfunc(test,100);有返回值,需要有值去接收
    cout<<val1<<endl;
    return 0;
}

打印结果:

Test funb10 Test func100 100

注意:<int(Test&,int )>尖括号中传入的是类型!


一个回调函数的例子:

/*function 一个回调函数的例子*/
class Test
{
    std::function<void()> callback;
public:
    Test(const std::function <void()>&f):callback(f){}
    void notify()
    {
        callback();
    }

};

class Foo
{
public:
    void operator()(void)
    {
        cout<<__FUNCTION__<<endl;
        cout<<__TIME__<<endl;
    }
};
int main()
{
    Foo foo;
    Test test(foo); 通过foo对象去激活foo中的仿函数 !
    test.notify();
    return  0;
}

可调动对象之--------
lamda表达式


2 .BIND与FUNCTION 示例:

/bind/
//作用1:将可调用对象与其参数一起绑定成一个仿函数
//作用2:将多元(参数个数为n,n>1) 可调用对象转成一元或(n-1)元,即只绑定部分参数

#include<iostream>
#include<functional>
using namespace std;
class Test
{
public:
    int val;
    Test(int x =0):val(x){}
    void output(int a,int b)
    {
        cout<<"a ="<<a<<"  b = "<<b<<"  val = "<<val<<endl;
    }

};
void output(int a,int b)
{
    cout<<"a ="<<a<<"  b = "<<b<<endl;
}
int main()
{   

    function<void(int ,int)>Function = output;
    auto pfun = std::bind(Function,10,20); 
    pfun();
    pfun(1,2); //此时的传入的参数并不起作用,因为绑定时已经给了固定的参数;
    auto pfuna = std::bind(Function,20); //error 格式中必须给两个参数
    auto pfunb = std::bind(Function,std::placeholders::_1,20);//第一个参数位给出占位符,
    //那么pfun(1,2)的第一个位置就被1占了;
    pfunb(1,2);
    Test test(10);
    auto pfunc = std::bind(&Test::output,test,std::placeholders::_1,placeholders::_2);
    //pfun;//没用调动可调动对象
    pfunc(1,2);
    ****************************************************************
    
    bind直接执行可调动对象:
    
    *括号内给值-> bind直接执行可调动对象*
    std::bind(&Test::output,test,std::placeholders::_1,placeholders::_2)(100,200); 
    ****************************************************************
    *function 加bind调动类对象成员方法*
    Test test1(10);
    std::function<void(Test&,int,int)>Function1 = &Test::output;
    std::bind(Function1,test1,placeholders::_1,placeholders::_2)(200,300);
    ****************************************************************
    *注意占位符和提取符的说法:*
    std::function<void(Test&,int,int)>Function2 = &Test::output;
    //std::bind(Function2,test1,placeholders::_1,placeholders::_3)(200,300);//error
     std::bind(Function2,test1,placeholders::_1,placeholders::_3)(100,200,300);//ok,第三个占位符可以提取到第三个参数

    
    return  0;

}

lamda表达式:

int main()
{   
    int x= 10,z=20;
    // auto val = [](int a)->int {
    //     return a+1;
    // };
    
    //cout<<val(1);
    // auto val = [=]() -> int{
    //     return x+10;
    // };
    // cout<<val(); //无参也要写括号  //reuslt::20

    auto val = [&]() ->int {
        x += 1000;
        return x;
    };
    cout<<"val = "<<val()<<endl;  //必须执行完VAL()后x的值才发生变化。
    cout<<"x = "<<x<<endl;
    /*无返回值的测试*/
    [&]() ->void {
        x += 1000;
    };
    cout<<"val = "<<val()<<endl;  
    cout<<"x = "<<x<<endl;
    cout<<"val = "<<val()<<endl;
    cout<<"x = "<<x<<endl;
    //带形参的测试:
    auto num = [x,&z](int y)->int {
        return x+(z++);
    };
    cout<<"num = "<<num(1)<<endl;
    cout<<z<<endl;
    //只引用形式捕获z,其他为隐式的以值捕获
    auto num1 = [=,&z](int y)->int{
        return x+(z++);
    };
    cout<<"num1 = "<<num1(1)<<endl;
    cout<<z<<endl;
    //只以值捕获z,其他为隐式的以引用捕获
    auto num2 = [&,z](int y)->int{
        cout<<"lamda"<<x<<endl;
        return (x++)+z;
    };
     cout<<"num2 = "<<num2(1)<<endl;
    cout<<"x"<<x<<endl;
    return 0;
}

在这里插入图片描述


线程的几种执行方式

1.thread的使用

    void funa(int x){cout<<"funa"<<endl;}
    void funb(int *p){cout<<"funb"<<endl;}  
    void func(int &x){cout<<"func"<<endl;
    x+=10;}
int main()
{   
    int x=10;
    int *p =&x;
    thread tha(funa,1);
    thread thb(funb,p);
    
    //thread thd(func,x); //error 函数无法以引用接收
    thread thc(func,std::ref(x)); //ok
    tha.join();
    thb.join();
    thc.join();
    //thd.join();
    cout<<x<<endl;
    return 0;

}

结果:

funa
funb
func
20

/利用using 定义函数指针/

void fun(int x,int y)
{   
    cout<<"nihao:fun"<<std::endl;
}
  using PFUN = void (*)(int , int);
  PFUN funt = fun; //ok
  std::thread thp(funt,2,2);//ok

3.线程调动类成员方法

typedef void (*pfun)();
using PFUN = void (*)(void);
class mythread
{
public:
    mythread(int val):val_(val)
    {}
    int val_;
public:
    void fun_thread(int val)
    {
        cout<<val_<<endl;
        cout<<val<<endl;
    }

};
int main()
{
 	mythread my1;
    std::thread thc(&mythread::fun_thread,&my1,100);
    thc.join();
    return 0;
}

4./线程函数是仿函数的例子/

/*线程函数是仿函数的例子*/
class Test
{
public:
    void operator()(int x,int y)
    {
        cout<<"add"<<x+y<<endl;
    }
    void add(int x,int y){
        cout<<"add 普通成员函数"<<x+y<<endl;
    }
};
int main()
{
    std::thread tha(Test{},1,2); //函数重载直接调动类的成员仿函数
    Test test;
    std::thread thb(&Test::add,&test,1,2); //调动成员函数
    thb.join();
    tha.join();
    return 0;
}

5./强转的例子/

class Test1
{
public:
int val = 190 ;
using PFUN = void (*)(int , int);
public:
static void add(int a,int b)
{
    int c=a+b;
    cout<<"add c"<<c<<endl;
}
operator PFUN()const
{
    return &add;
}
operator int()const
{
    return val;
}
};
int main()
{
    Test1 test1;
    int num =test1; //会调动重载的强转函数 operator int()
    test1(12,23); //result::add 35 .其实是下面的语句:
    //test.operator Test::PFUN()(12,23);
    
    return 0;
}

test1(12,23); 调动过程:
test1后面的括号代表调动其重载函数,12,23为add的参数匹配,最后调动ADD函数。


lamda:

int main()
{

   /*lamda*/
    std::thread thc([&](int x_) -> void {

        x += x_; //这里x要用就必须被捕获,注意不能被值捕获(这里值被修改)
    },100);
    std::thread thc([=]()->void {
        printf("lamda \n");
    });
    
    thc.join();
    cout<<num<<endl;// 110
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值