c11

      
      

一:stl遍历新方法
1.std::for_each遍历调用一个函数并传一个*it的用法
  #include<algorithm>
  std::for_each(.begin(),.end(),函数);
2.auto的简化新遍历用法
   for(auto it =arr.begin();it!=arr.end();++it)
3.auto全范围新遍历用法
   for(auto   var:arr){}
   for(auto&  var:arr){}
   for(const auto   var:arr){}
   for(const auto&  var:arr){}
   切记:该用法下所取的不是迭代器,而是容器里存的value_type,map对应pair;
 4.对于取中间一段遍历,新用法没有简便办法,只能像2.简化,原始用法
二:lambda表达式,简称"中括号,小扩号,大扩号"
lambda表达式其实是一个末尾加了const修饰的函数
全语法:  [变量捕获] (参数)opt->ret{函数体}
实际用法:[]()ret{}
作用域:当前作用域,类作用域,主要通过参数传值方式和作用变量体现
参数传递方式:引用,按值
作用变量:无变量即表示全部的意思

1.->可省略,不清楚是做什么用的
2.没有参数()可省略变成:[]ret{}
3.返回值无,或可以推导变成以下:[]{}
4.[]很重要,代表{}内使用的变量权限
  <1>.2个作用域内默认捕获方式,若没指明,即不能使用外部变量,如[]
  [&]:表达示中使用的全部外部变量按引用传递(默认捕获方式)
  [=]:表达示中使用的全部外部变量按值传递(默认捕获方式)
  <2>.自由组合捕获方式
  [this]:此表达式视为该类的成员变量,可访问类的全部成员
  [var]:表达示中使用的var按值传递,表达示中不使用除var的外部变量
  [&var]:表达示中使用的var按引用传递,表达示中不使用除var的外部变量
  以下可以任意组合:但是一个变量的权限不能与指明的默认捕获方式重复,表达式会内建函数把需要的变量丢进函数内,同个权限的变量不能出现两次
  [=,a,b]     :对
  [this,a,b]  :对
  [this,&,b]  : 对
  [=,a,b]  :错误  a,b本来就已是按值捕获
  [=a]     :错误 不能加=
  [&,a,&b] :错误 b和前面冲突
  意外:经实际程序验证,按值传递的变量,连修改变量的权限都没,和函数完全不一样,只能把值赋给函数中申请的变量再作修改
  结论:lambda表达式其实是一个末尾加了const修饰的函数
  auto f = [x,&xx](int var)
 {
  x+=5;  //此步要报错,提示改成&%
  x = 10;//此步要报错,提示改成&%
  int t = x;
  t++;
  xx--;
  return var + x + xx ;
 };
  5.opt
    <1>.mutable
      表达式选项目前仅遇到过这种,表达式内部的传值变量也可以修改了,突破const限制;
      若有mutable修饰的表达式,()参数即使没参数也不能省
  6.用法
    <1>.直接可以把表达式赋给std::function
         std::function<int(int(int)> f = [](int a){return a;};
         f(123);
    <2>.直接用于构造std::bind
        std::function<int(int(int)> f = std::bind([](int a){return a;},123);
        f(123);
    <3>.把表达式直接赋给auto 变量,由变量来调用
        auto f = [](int a){return a;};
        f(123);
    <4>.把表达式赋给函数指针,由指针调用
        using func = int(*)(int);
        func f = [](int a){return a;};
        f(123);
三:using 和 typedef
    using 可以代替 typedef
    using 可以定义别名模板,typedef不可以
    1.函数指针的定义区别
      typedef int(*func_t)(int);
      using  func_t int(*)(int);
    2.一个模板类因为有模板参数,所以该类不可能直接用typedef,typedef只能重定义一个明确的类
      template<class T>
      class Object
      {};
      -----------------------------
      typedef Object  newClass;  //错误,因为模板能数的原因
      template<class T> using NewT = struct Object<T>;//using 的用处比typedef强的地方在此
      附:typedef处理模板类的传统方法
      template<class T>
      class Object
      {
        public:
        typedef Object<T>   NewT;
      };
      Object::NewT t;//定义变量
四:函数回调
    函数回调主要关注以下几类
    1.函数指针
    void (*funcptr)(void) = &func;
    funcptr();
    2.类成员函数指针
    struct A
    {
      void memfun(void)
       {
       }
    };
    void (A::*memfuncptr)(void) = &A::memfun;
    A a;
    (a.*memfuncptr)();
    3.仿函数
    struct foo
    {
      void operator()(void)
      {
      }
    };
    foo f;
    f();
    4.静态成员函数
    (有点复杂)
     
  五.std::function函数包装器的用法
    除类成员函数外,可直接用静态函数,普通函数,仿函数进行赋值
    切记:不能容纳类成员函数
    1.绑定普通函数
    std::function<void(void)> f = func;
    2.绑定静态函数
    std::function<void(void)> f = Foo::foo;
    3.绑定仿函数
    Foo b;//具有仿函数的对像
    std::function<void(void)> f = b;//绑定仿函数,注意生命周期
    4.绑定类成员函数,必须要用std::bind函数才行
    切记:传的都是指针
    std::function<void(void)> f = std::bind(&Foo::fun,&foo);
  六.std::bind函数绑定器的用法
    说明:std::bind实际上生成了一个仿函数,可绑定部分参数,也可以不绑定
    1.我们可以将该仿函数直接赋值给std::function
          std::function<void(void)> f = std::bind(&Foo::fun,&foo);
        
    2.std::bind既然是生成一个仿函数,可以自身执行而不依赖std::function
          std::bind(output)(1,2);//可以直接生成函数调用
          std::bind(output,1,2)();//上下效果一样
    2.std::bind可以绑定std::function能包装的各种函数类型
      普通函数
      静态函数
      仿函数
      类成员函数
          std::function<void(void)> f = std::bind(&Foo::fun,&foo);
      类成员(比较复杂,可以把一个类的成员对像绑定成一个返回该对像的引用的函数,然后可以为此引用赋值,以修改该引用)
          std::function<int&(void)> f = std::bind(&Foo::i,&foo);
          f() = 12;
     
    3. 参数占位std::placeholders::_1-_8
      意义:std::bind(函数,原函数参数1,原函数参数2,原函数参数3...)扩号中的参数出现的位置顺序和原函数一样的顺序
      std::placeholders::_1-_8参数占位符主要是把生成的仿函数的位置对原函数的位置
      如:
        std::bind(output,std::placehoders::_1,std::placehoders::_2)(1,2);//即output(1,2);
        std::bind(output,std::placehoders::_2,std::placehoders::_1)(1,2);//即output(2,1);
        std::bind(output,5,std::placehoders::_2)(1,2);                   //即output(5,2);
     4. 组合函数的用法,暂且不管,太复杂了
   七 .线程std::thread
      线程用法很简单
      创建方法(线程一创建就开始运行,参数在构造函数时传)
      1.用函数直接构造创建
        std::thread t(func);
      2.用std::function间接构造创建 
        std::function<void(void)> f(func);
        std::thread t(f);
      3.用std::move移动构拷贝构造或是赋值构造
        std::thread t2 = std::move(t);
        std::thread t2(std::move(t));
        移动后的原来线程不能再调用join之类的函数,否则为崩
      4.用类成员函数构造
        TPrintf tb;
        std::thread t3(&TPrintf::Printf, &tb);
        疑问:对像的生命周期和线程生命周期不一样怎么办
      5.线程其它用法和函数
          .join()   同步阻塞等待
          .detach() 分离线程不阻塞,分离后的生命周期目前测出和主线程周期一样
          .get_id() 得到ID
          std::thread::hardware_concurrency() 得到CPU个数
          std::this_thread::sleep_for(std::chrono::seconds(3));   线程睡眠
     八.线程互斥
        互斥分为可重入和非可重入,超时和非超时,C11提供4种互斥
        为了与过去保持技术上的一致,只掌握非可重入的不带超时的std::mutex
        1.std::mutex实际上是之前自己封装的互斥锁,现在C11已经直接提供加锁和解锁
          .lock();//加锁
          .unlock();//解锁
        2.std::lock_guard自动加锁,传入互斥对像构造即可,离开作用域自动解锁
          std::lock_guard(std::mutex& mutex);
      九.条件变量   
        要求任何在等待该条件变量的线程必须先获取锁才能等待该条件
        1.所有互斥量,自动析构锁
          std::condition_variable_any   std::lock_guard  std::mutex/std::timed_mutex...
        2.只对std::mutex有效,并且只能用std::unique_lock
          std::condition_variable       std::unique_lock  std::mutex 
        用法:两者完全一样的用法,std::condition_variable的性能要高一点
              两都都是在加锁成功后,等待一个条件变量,等待过程中释放锁,条件满足后重新加锁
              .wait(std::mutex& mutex);
              .wait(std::mutex& mutex,lambda);
              .notyfy_once();
              .notyfy_all();
             


      
    
  
  
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值