zoukankan      html  css  js  c++  java
  • lambda、pair、智能指针及时间函数

    Lambda 表达式

    auto f1 = [](int x, int y) { return x + y; };
    cout << f1(2, 3) << endl;

    int n = [] (int x, int y) { return x + y; }(5, 4);

    Lambda 的类型是个不具名function object

    #include <functional>

    std::function<int(int,int)> returnLambda() //返回类型为lambda

    {

      return [](int x, int y){

        return x*y;

        };

    }

    auto lf = returnLambda();

    cout << lf(6,7) <<endl;

    int var;
    decltype(var) var1; int

    const int&& fx();
    decltype(fx()); const int&&


    templeate<typename T1, typename T2>
    decltype(x+y) add(T1 x, T2 y); //错误x,y未在作用域

    templeate<typename T1, typename T2>
    auto add(T1 x, T2 y) -> decltype(x+y); //OK

    通用工具
    Pair <utility>

    pair<T1,T2> p;
    pair<T1,T2> p(val1,val2);
    p.first;
    p.second;
    get<0>(p); //p.first
    get<1>(p); //p.second
    p1.swap(p2);
    swap(p1,p2);
    make_pair(val1,val2);


    Touple 扩展pair,建议至少10个 <tuple>

    tuple<int,float,string> t1(41,6.3,"nico");
    get<0>(t1);

    make_tuple(41,6.3,"nico");


    元素可以是reference
    string s;
    tuple<string&> t(s);
    get<0>(t) = "hello";

    ref()、cref() <functional>

    string s;
    make_tuple(ref(s));


    tuple<int,float,string> t(77,1.1,"s");
    int i;
    float f;
    string s;
    tie(i,f,s) = t; //建立一个内含reference的tuple


    智能指针 <memory>

    unique_ptr 独占式拥有
    unique_ptr<int> up(new string("nico"));
    (*up)[0] = 'N';
    up->...


    不允许赋值
    unique_ptr<int> up = new int; //ERROR
    必须直接初始化
    unique_ptr<int> up(new int); //OK

    unique_ptr<string> up;
    up = nullptr;或up.reset(); //其内delete且赋值为nullptr


    unique_ptr<string> up(new string("nico"));
    string *sp = up.release();

    if (up != nullptr)

    if (up.get() != nullptr)

    转移拥有权
    string *sp = new string("hello");
    unique_ptr<string> up1(sp);
    unique_ptr<string> up2(sp);//ERROR
    unique_ptr<string> up3(std::move(up1));

    函数参数是unique_ptr,则参数需要move

    void sink(unique_ptr<ClassA> up)
    {}

    unique_ptr<ClassA> up(new ClassA);
    sink(std::move(up));//调用之后up为空
    //若想调用之后up也有效,则参数设为引用unique_ptr<ClassA> &up

    函数返回unique_ptr,其拥有权移至调用端场景
    unique_ptr<ClassA> source()
    {
    unique_ptr<ClassA> ptr(new ClassA);
    ...
    return ptr;
    }


    针对Array

    unique_ptr<string> up(new string[10]);//ERROR,能编译

    偏特化版本 自行调用delete[]
    unique_ptr<string[]> up(new string[10]);
    此版本不提供* 和 ->操作符,该而提供[]
    *up; //ERROR
    up[0];


    当所指对象要求的不只是调用delete或delete[],就必须具体制定自己的deleter
    class ClassADeleter
    {
    public:
    void operator () (ClassA* p){
    cout << "call delete for ClassA object" << endl;
    delete p;
    }
    };

    unique_ptr<ClassA,ClassADeleter> up(new ClassA());

    如果你给的是个函数或lambda,就必须声明deleter的类型为void(*)(T*)或std::function<void(T*)>, (头文件<functional>)
    要不就使用decltype

    unique_ptr<int, void(*)(int*)> up(new int[10],
    [](int* p){
    ...
    delete[] p;
    });

    unique_ptr<int, std::function<void(int*)>> up(new int[10],
    [](int* p){
    ...
    delete[] p;
    });

    auto l = [](int* p){
    ...
    delete[] p;
    };
    unique_ptr<int,decltype(l)>> up(new int[10], l);

    shared_ptr 可以赋值、拷贝、比较

    shared_ptr<string> pNico(new string("nico"));
    shared_ptr<string> pNico{new string("nico")};

    shared_ptr<string> pNico = new string("nico");//ERROR

    shared_ptr<string> pNico = make_shared<string>("nico");

    shared_ptr<string> pNico;
    pNico = new string("nico");//ERROR
    pNico.reset(new string("nico"));

    pNico.use_count();//某个对象的当前拥有者数量


    定义自己的Deleter
    shared_ptr<string> pNico(new string("nico"),
    [](string* p){
    cout << "delete " << *p << endl;
    delete p;
    });

    针对Array
    shared_ptr<int> p(new int[10]);//ERROR,能编译

    shared_ptr<int> p(new int[10],
    [](int* p){
    delete[] p;
    });

    shared_ptr<int> p(new int[10],
    std::default_delete<int[]>());

    此与unique_ptr不同
    unique_ptr<int> p(new int[10]);//能编译
    shared_ptr<int> p(new int[10]);//ERROR,不能编译

    shared_ptr不提供operator []

    p.get()[2] = 2;
    等同于
    (&*p)[2] = 2;


    误用
    int* p = new int;
    shared_ptr<int> sp1(p);
    shared_ptr<int> sp2(p);
    ERROR,sp1、sp2都会在丢失p的拥有权时释放相应资源即delete


    shared_ptr<int> sp1(new int);
    shared_ptr<int> sp2(sp1);


    sp.reset();//放弃拥有权并重新初始化,使它像是empty
    sp.reset(ptr);//放弃拥有权并重新初始化(拥有*ptr),使用默认delete
    sp.reset(ptr,del);

    make_shared(...);//
    auto sp3 = make_shared<int>(1);


    sp.get();//返回存储的pointer
    *sp
    sp->
    sp.use_count()
    if (sp) //判断sp是否为empty


    挑选最大最小值 <algorithm>
    min(a,b);
    min(a,b,cmp);
    min(initlist)
    min(initlist,cmp)
    max...
    minmax(a,b) //返回pair<>,其first是最小值,second是最大值
    minmax(a,b,cmp)
    minmax(initlist)
    minmax(initlist,cmp)


    swap() <utility>

    namespace std{
    template<typename T>
    inline void swap(T& a, T& b)...{
    T tmp(std::move(a));
    a = std::move(b);
    b = std::move(tmp);
    }
    }

    Class ratio<>的编译期分数运算 <ratio>


    ratio<5,3>; 3分之5
    ratio<5,3>::num 5
    ratio<5,3>::den 3

    ratio<0>; //0, den默认为1

    Clock和Timer <chrono>


    duration 时间段 = tick(片刻数)*时间单位(分数) 1.5个1/3秒

    timepoint 时间点 = 一个duration和一个opoch(起始点)


    std::chrono::duration<int> twentySeconds(20);
    std::chrono::duration<double, std::ratio<60>> halfAMinute(0.5);
    std::chrono::duration<long, std::ratio<1,1000>> oneMillisecond(1);

    std::chrono::huors
    std::chrono::minutes
    std::chrono::seconds twentySeconds(20);
    std::chrono::milliseconds
    std::chrono::microseconds
    std::chrono::nanoseconds

    隐式转换可以转换至较精准的单位类型
    可以将小时转换为秒,反之则不行


    duration d
    d.count() //返回d的tick数量
    duration_cast<D>(d) //显示转换
    duration::zero() //获得长度为0的duration
    duration::max() //
    duration::min()
    duration::rep() //获得tick的类型
    duration::period() //获得单位类型的类型


    Clock 和 Timepoint

    Clock 定义一个epoch 和一个tick周期
    clock::duration 获得clock的duration类型
    clock::rep 获得tick类型 <=> clock::duration::rep
    clock::period 获得单位类型的类型 <=> clock::duration::period
    clock::time_point 获得clock的timepoint类型
    clock::is_steady 如果clock是steady则为TRUE
    clock::now() 获得一个表示目前时间的time_point


    C++标准库提供了三个clock

    1.system_clock 系统的即时时钟 tick: 0.000100 milliseconds
    is_steady:false
    to_time_t()
    form_time_t()


    2.steady_clock tick: 1.000000 milliseconds


    3.high_resolution_clock 当前系统中带有最短tick周期的clock tick: 0.000100 milliseconds
    is_steady:true


    #include <chrono>
    #include <ctime>
    #include <string>
    #include <iostream>

    using namespace std;
    using namespace std::chrono;

    string asString(const system_clock::time_point& tp)
    {
    time_t t = system_clock::to_time_t(tp);
    string ts;// = ctime(&t); //转换为日历时间
    char arr[100];
    memset(arr, 0, 100);
    ctime_s(arr, 100, &t);
    ts = arr;
    if (ts.size() > 0)
    ts.resize(ts.size() - 1); //移除末端的newline字符
    return ts;
    }

    int main(int argc, _TCHAR* argv[])
    {
    //epoch:由clock的time_point的默认构造函数产出
    system_clock::time_point tp;
    //等价于
    time_point<system_clock> tp1;
    cout << "epoch: " << asString(tp) << endl;

    tp = system_clock::now();
    cout << "now: " << asString(tp) << endl;

    tp = system_clock::time_point::min(); //出错??
    cout << "min: " << asString(tp) << endl;

    tp = system_clock::time_point::max(); //出错??
    cout << "max: " << asString(tp) << endl;


    return 0;
    }


    C 提供的 Date/Time函数

    <time.h> --> <ctime>

    clock_t 数值类型 long ,表示elapsed CPU time,由clock()返回
    time_t 数值类型,表现timepoint
    struct tm 被解开之日历时间的类型


    clock() 获得elapsed CPU time,该程序从启动到函数调用占用CPU的时间,
    单位是1/CLOCKS_PER_SEC秒 1/1000 即 毫秒
    time() 获得当前时间,是个数值time_t t; time(&t);//same as:t = time(NULL);
    difftime() 获得2个time_t之间的差值,double,单位秒


    localtime() 转换time_t成为一个struct tm,考虑时区
    gmtime() 转换time_t成为一个struct tm,不考虑时区
    asctime() 转换struct tm成为一个标准日历时间字符串
    strftime() 转换struct tm成为一个用户自定义的日历时间字符串
    ctime() 转换time_t成为一个标准日历时间字符串,考虑时区
    相当于asctime(localtime(t))
    mktime() 转换struct tm成为一个time_t并查询其为星期中的哪一天,和一年中的第几天

    struct tm
    {
    int tm_sec; // seconds after the minute - [0, 60] including leap second
    int tm_min; // minutes after the hour - [0, 59]
    int tm_hour; // hours since midnight - [0, 23]
    int tm_mday; // day of the month - [1, 31]
    int tm_mon; // months since January - [0, 11]
    int tm_year; // years since 1900
    int tm_wday; // days since Sunday - [0, 6]
    int tm_yday; // days since January 1 - [0, 365]
    int tm_isdst; // daylight savings time flag
    };


    _time64和time_t默认情况下,等效于 __time64_t
    如果需要强制编译器将解释time_t为旧的 32 位time_t,你可以定义 _USE_32BIT_TIME_T。
    不建议这样做,因为应用程序可能会在 2038 年 1 月 18 日后失效;64 位平台上不允许使用此宏。

    clock_t为long,一个带符号的 32 位整数,和CLOCKS_PER_SEC宏定义为 1000
    这样,最多时钟函数返回值为 2147483.647 秒,或大约 24.8 天
    所以一般不使用此函数

  • 相关阅读:
    Prim算法以及Kruskal算法
    PAT甲级考前整理(2019年3月备考)之三,持续更新中.....
    PAT甲级考前整理(2019年3月备考)之一
    PAT甲级考前整理(2019年3月备考)之二,持续更新中.....
    linux下挂载U盘
    opencv2已有的情况下,安装opencv3以及对应的opencv_contrib
    二维数组和二级指针做函数参数的问题
    ubuntu14.04下 python2.7怎么链接到安装在指定文件夹的opencv3
    使用opencv的nonfree模块
    PaddlePaddle开源平台的应用
  • 原文地址:https://www.cnblogs.com/xslwm/p/9393658.html
Copyright © 2011-2022 走看看