C++相关闲碎记录(3)

1、reference wrapper

例如声明如下的模板:

template <typename T>
void foo(T val);

 如果调用使用:

int x;
foo(std::ref(x));

T变成int&,而使用调用

int x;
foo(std::cref(x));

T变成const int&。

 这个特性被C++标准库用在各个地方,例如:

make_pair()用此特性于是能够创建一个pair<>of reference
make_tuple()用此特性可以创建一个tuple<>of reference 
 

std::vector<MyClass&> coll;       //error
std::vector<std::reference_wrapper<MyClass>> coll;    //ok

2、function type wrapper

#include <iostream>
#include <vector>
#include <functional>
using namespace std;

void func(int x, int y) {
    std::cout << "func" << std::endl;
}

class C {
public:
    void memfunc(int x, int y) const{
        std::cout << "C::memfunc" << std::endl;
    }
};

int main()
{
    std::vector<std::function<void(int,int)>> tasks;
    tasks.push_back(func);
    tasks.push_back([](int x, int y) {
                        std::cout << "lambda" << std::endl;
                    });
    for (std::function<void(int,int)> f : tasks) {
        f(3, 33);
    }

    std::function<void(const C&, int, int)> mf;
    mf = &C::memfunc;
    mf(C(), 2, 3);
    return 0;
}
输入:
func
lambda
C::memfunc

3、挑选最小值和最大值

auto extremes = std::minmax({px, py, pz}, [](int*a, int*b) {
                        return *a < *b;                        
                    });
两值互换:
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);
    }
}

4、class ratio<>

#include <ratio>
#include <iostream>
using namespace std;

int main()
{
   typedef ratio<5,3> FiveThirds;
   cout << FiveThirds::num << "/" << FiveThirds::den << endl;

   typedef ratio<25,15> AlsoFiveThirds;
   cout << AlsoFiveThirds::num << "/" << AlsoFiveThirds::den << endl;

   ratio<42,42> one;
   cout << one.num << "/" << one.den << endl;

   ratio<0> zero;
   cout << zero.num << "/" << zero.den << endl;

   typedef ratio<7,-3> Neg;
   cout << Neg::num << "/" << Neg::den << endl;
}
输出:
5/3
5/3
1/1
0/1
-7/3

 5、duration

#include <ratio>
#include <iostream>
#include <chrono>
using namespace std;

int main()
{
   std::chrono::duration<int>                         twentySeconds(20);  //以秒为单位
   std::chrono::duration<double, std::ratio<60>>      halfAMinute(0.5);   //以60秒为单位
   std::chrono::duration<long, std::ratio<1, 1000>>   oneMillisecond(1);  //以1/1000秒为单位

   std::chrono::seconds         twentySeconds(20);
   std::chrono::hours           aDay(24);
   std::chrono::milliseconds    oneMillisecond(1);
}

// 将毫秒单位的duration切割为小时,分钟,秒,毫秒 

#include <ratio>
#include <iostream>
#include <chrono>
#include <iomanip>
using namespace std;
using namespace std::chrono;

milliseconds ms(7255042);

template <typename V, typename R>
ostream& operator<<(ostream& os, const chrono::duration<V,R>& d) {
    os << "[" << d.count() << " of " << R::num << "/" << R::den << "]";
    return os;
}

// 将毫秒单位的duration切割为小时,分钟,秒,毫秒
int main()
{
    hours hh = duration_cast<hours>(ms);
    minutes mm = duration_cast<minutes>(ms%chrono::hours(1));
    seconds ss = duration_cast<seconds>(ms%chrono::minutes(1));
    milliseconds msec = duration_cast<milliseconds>(ms%chrono::seconds(1));

    cout << "raw: " << hh << "::" << mm << "::"
         << ss << "::" << msec << endl;
    cout << "    " << setfill('0') << setw(2) << hh.count() << "::"
                                   << setw(2) << mm.count() << "::"
                                   << setw(2) << ss.count() << "::"
                                   << setw(2) << msec.count() << endl;
}
#include <ratio>
#include <iostream>
#include <chrono>
#include <iomanip>
using namespace std;
using namespace std::chrono;

template <typename C>
void printClockData ()
{
    using namespace std;

    cout << "- precision: ";
    // if time unit is less than or equal to one millisecond
    typedef typename C::period P;   // type of time unit
    if (ratio_less_equal<P,milli>::value) {
        // convert to and print as milliseconds
        typedef typename ratio_multiply<P,kilo>::type TT;
        cout << fixed << double(TT::num)/TT::den
             << " milliseconds" << endl;
    }
    else {
        // print as seconds
        cout << fixed << double(P::num)/P::den << " seconds" << endl;
    }
    cout << "- is_steady: " << boolalpha << C::is_steady << endl;
}

int main()
{
    std::cout << "system_clock: " << std::endl;
    printClockData<std::chrono::system_clock>();
    std::cout << "\nhigh_resolution_clock: " << std::endl;
    printClockData<std::chrono::high_resolution_clock>();
    std::cout << "\nsteady_clock: " << std::endl;
    printClockData<std::chrono::steady_clock>();
}
输出:
system_clock: 
- precision: 0.000001 milliseconds
- is_steady: false

high_resolution_clock:
- precision: 0.000001 milliseconds
- is_steady: false

steady_clock:
- precision: 0.000001 milliseconds
- is_steady: true

下面的程序将timepoint赋值给tp,并转换为日历表示法,window运行会报错,LInux下运行正常:

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

std::string asString (const std::chrono::system_clock::time_point& tp)
{
    // convert to system time:
    std::time_t t = std::chrono::system_clock::to_time_t(tp);
    std::string ts = std::ctime(&t);    // convert to calendar time
    ts.resize(ts.size()-1);             // skip trailing newline
    return ts; 
}

int main()
{
    // print the epoch of this system clock:
    std::chrono::system_clock::time_point tp;
    std::cout << "epoch: " << asString(tp) << std::endl;

    // print current time:
    tp = std::chrono::system_clock::now();
    std::cout << "now:   " << asString(tp) << std::endl;

    // print minimum time of this system clock:
    tp = std::chrono::system_clock::time_point::min();
    std::cout << "min:   " << asString(tp) << std::endl;

    // print maximum time of this system clock:
    tp = std::chrono::system_clock::time_point::max();
    std::cout << "max:   " << asString(tp) << std::endl;
}
输出:
epoch: Thu Jan  1 08:00:00 1970
now:   Thu Nov 30 21:29:29 2023
min:   Tue Sep 21 08:18:27 1677
max:   Sat Apr 12 07:47:16 2262
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
using namespace std;

string asString (const chrono::system_clock::time_point& tp)
{
    time_t t = chrono::system_clock::to_time_t(tp); // convert to system time
    string ts = ctime(&t);                          // convert to calendar time
    ts.resize(ts.size()-1);                         // skip trailing newline
    return ts; 
}

int main()
{
    // define type for durations that represent day(s):
    typedef chrono::duration<int,ratio<3600*24>> Days;

    // process the epoch of this system clock
    chrono::time_point<chrono::system_clock> tp;
    cout << "epoch:     " << asString(tp) << endl;

    // add one day, 23 hours, and 55 minutes
    tp += Days(1) + chrono::hours(23) + chrono::minutes(55);
    cout << "later:     " << asString(tp) << endl;

    // process difference from epoch in minutes and days:
    auto diff = tp - chrono::system_clock::time_point();
    cout << "diff:      "
         << chrono::duration_cast<chrono::minutes>(diff).count()
         << " minute(s)" << endl;
    Days days = chrono::duration_cast<Days>(diff);
    cout << "diff:      " << days.count() << " day(s)" << endl;

    // subtract one year (hoping it is valid and not a leap year)
    tp -= chrono::hours(24*365);
    cout << "-1 year:   " << asString(tp) << endl;

    // subtract 50 years (hoping it is valid and ignoring leap years)
    tp -= chrono::duration<int,ratio<3600*24*365>>(50);
    cout << "-50 years: " << asString(tp) << endl;

    // subtract 50 years (hoping it is valid and ignoring leap years)
    tp -= chrono::duration<int,ratio<3600*24*365>>(50);
    cout << "-50 years: " << asString(tp) << endl;
}
输出:
epoch:     Thu Jan  1 08:00:00 1970
later:     Sat Jan  3 07:55:00 1970
diff:      2875 minute(s)
diff:      1 day(s)
-1 year:   Fri Jan  3 07:55:00 1969
-50 years: Thu Jan 16 07:55:00 1919
-50 years: Wed Jan 27 08:00:43 1869

 6、timepoint与日历时间的转换

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

// convert timepoint of system clock to calendar time string
inline std::string asString(const std::chrono::system_clock::time_point& tp) {
    std::time_t t = std::chrono::system_clock::to_time_t(tp);
    std::string ts = ctime(&t);  // convert to calendar time
    ts.resize(ts.size()-1);      //skip trailing newline
    return ts;
}

// convert calender time to timepoint of system clock
inline std::chrono::system_clock::time_point
makeTimePoint(int year, int mon, int day, int hour, int min, int sec=0) {
    struct std::tm t;
    t.tm_sec = sec;
    t.tm_min = min;
    t.tm_hour = hour;
    t.tm_mday = day;
    t.tm_mon = mon - 1;
    t.tm_year = year-1900;
    t.tm_isdst = -1;
    std::time_t tt = std::mktime(&t);
    if (tt == -1) {
        throw "no valid system time";
    }
    return std::chrono::system_clock::from_time_t(tt);
}

int main() {
    auto tp1 = makeTimePoint(2023, 11, 30, 00, 00);
    std::cout << asString(tp1) << std::endl;

    auto tp2 = makeTimePoint(2023, 03, 23, 12, 33);
    std::cout << asString(tp2) << std::endl;
    return 0;
}
输出:
Thu Nov 30 00:00:00 2023
Thu Mar 23 12:33:00 2023

7、<cstring>中的定义式

//在ptr所指的前len个byte中找出字符c
memchr(const void* ptr, int c, size_t len)

//比较ptr1和ptr2所指的前len个byte
memcmp(const void* ptr1, const void* ptr2, size_t len)

//将fromPtr所指的前len个byte复制到toPtr
memcpy(void* toPtr, const void* fromPtr, size_t len)

//将fromPtr所指的前len个byte复制到toPtr(区域可重叠)
memmove(void* toPtr, const void* fromPtr, size_t len)

//将ptr所指的前len个byte赋值为字符c
memset(void* ptr, int c, size_t len)

 8、algorithm

(1)find
#include <algorithm>
#include <list>
#include <iostream>
using namespace std;

int main()
{
    list<int> coll;

    // insert elements from 20 to 40
    for (int i=20; i<=40; ++i) {
        coll.push_back(i);
    }

    // find position of element with value 3
    // - there is none, so pos3 gets coll.end()
    auto pos3 = find (coll.begin(), coll.end(),    // range
                      3);                          // value
    
    // reverse the order of elements between found element and the end
    // - because pos3 is coll.end() it reverses an empty range
    reverse (pos3, coll.end());

    // find positions of values 25 and 35
    list<int>::iterator pos25, pos35;
    pos25 = find (coll.begin(), coll.end(),  // range
                  25);                       // value
    pos35 = find (coll.begin(), coll.end(),  // range
                  35);                       // value

    // print the maximum of the corresponding range
    // - note: including pos25 but excluding pos35
    cout << "max: " << *max_element (pos25, pos35) << endl;

    // process the elements including the last position
    cout << "max: " << *max_element (pos25, ++pos35) << endl;
}
(2)find_if

查找最先出现的25或者35

#include <algorithm>
#include <list>
#include <iostream>
using namespace std;

int main()
{
    list<int> coll;

    // insert elements from 20 to 40
    for (int i=20; i<=40; ++i) {
        coll.push_back(i);
    }

    auto pos = find_if(coll.begin(), coll.end(),
                        [](int i) {
                            return i == 25 || i == 35;
                        });
    if (pos == coll.end()) {
        std::cout << "not found" << std::endl;
        exit(1);
    }
    list<int>::const_iterator pos25, pos35;
    if (*pos == 25) {
        // 先找到25
        pos25 = pos;
        pos35 = find(++pos, coll.end(), 35);
        std::cout << *pos35 << std::endl;
    } else {
        pos35 = pos;
        pos25 = find(++pos, coll.end(), 25);
        std::cout << *pos25 << std::endl;
    }
}

9、insert iterator

#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <iterator>
#include <deque>
#include <iostream>
using namespace std;

int main()
{
    list<int> coll1 = {1, 2, 3, 4, 5, 6, 7, 8};
    vector<int> coll2;

    copy(coll1.begin(), coll1.end(), back_inserter(coll2));

    deque<int> coll3;
    copy(coll1.begin(), coll1.end(), front_inserter(coll3));

    set<int> coll4;
    copy(coll1.begin(), coll1.end(), inserter(coll4, coll4.begin()));

    for (auto &ele : coll2) {
        std::cout << ele << " ";
    }
    std::cout << std::endl;
    for (auto &ele : coll3) {
        std::cout << ele << " ";
    }
    std::cout << std::endl;
    for(auto & ele : coll4) {
        std::cout << ele << " ";
    }
}
输出:
1 2 3 4 5 6 7 8 
8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8

inserter的作用是在“初始化时接受的第二个实参”所指的位置的前面插入元素,内部调用成员函数insert(),并以新值和新位置作为实参传入,所有的STL容器都提供insert()成员函数,这是唯一可以用于关联式容器身上的一种预定义inserter。

10、stream iterator 

 

#include <algorithm>
#include <vector>
#include <iterator>
#include <string>
#include <iostream>
using namespace std;

int main()
{
    vector<string> coll;

    // 使用ctrl+z 回车进行终止
    copy(istream_iterator<string>(cin), 
         istream_iterator<string>(),
         back_inserter(coll));

    sort(coll.begin(), coll.end());

    unique_copy(coll.cbegin(), coll.cend(), 
                ostream_iterator<string>(cout, "\n"));
}

11、reverse iterator 

#include <algorithm>
#include <vector>
#include <iterator>
#include <string>
#include <iostream>
using namespace std;

int main()
{
    vector<int> coll;

    for (int i = 1; i <= 9; i++) {
        coll.push_back(i);
    }

    copy(coll.crbegin(), coll.crend(), 
         ostream_iterator<int>(cout, " "));
}
输出:
9 8 7 6 5 4 3 2 1 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/210442.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】1094. 拼车-2023.12.2

题目&#xff1a; 1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi…

vue中中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…

@2023 中国家居家具行业数字化转型分析与案例解读|商派徐礼昭

作者&#xff1a;徐礼昭&#xff08;商派市场负责人&#xff0c;重构零售实验室负责人&#xff09; 中国的家居家具行业面临着市场竞争激烈、消费者需求多变等诸多挑战。为了应对这些挑战&#xff0c;许多品牌企业开始探索数字化转型的道路&#xff0c;以提升竞争力并满足消费…

非应届生简历模板13篇

无论您是职场新人还是转行求职者&#xff0c;一份出色的简历都是获得心仪岗位的关键。本文为大家精选了13篇专业的非应届生简历模板&#xff0c;无论您的经验如何&#xff0c;都可以灵活参考借鉴&#xff0c;提升自己的简历质量。让简历脱颖而出&#xff0c;轻松斩获心仪职位&a…

np.array无法直接用matplotlib画图,因为需要借用np.squeeze先转化

文章目录 前言一、使用步骤1.没使用np.squeeze转化2.使用np.squeeze转化 前言 实际工作中&#xff0c;时而难免会遇见np.array无法直接用matplotlib画图的情况&#xff0c;这个时候&#xff0c;是因为在画图之前少了一个步骤&#xff0c;需要先借用np.squeeze先转化 一、使用步…

ES通过抽样agg聚合性能提升3-5倍

一直以来&#xff0c;es的agg聚合分析性能都比较差&#xff08;对应sql的 group by&#xff09;。特别是在超多数据中做聚合&#xff0c;在搜索的条件命中特别多结果的情况下&#xff0c;聚合分析会非常非常的慢。 一个聚合条件&#xff1a;聚合分析请求的时间 search time a…

【算法】Rabin-Karp 算法

目录 1.概述2.代码实现3.应用 更多数据结构与算法的相关知识可以查看数据结构与算法这一专栏。 有关字符串模式匹配的其它算法&#xff1a; 【算法】Brute-Force 算法 【算法】KMP 算法 1.概述 &#xff08;1&#xff09;Rabin-Karp 算法是由 Richard M. Karp 和 Michael O. R…

免费采集工具推荐,好文章值得收藏

采集工具的作用 在互联网的海洋中&#xff0c;有许多强大的免费采集工具&#xff0c;它们为用户提供了便捷、高效的方式&#xff0c;帮助用户从各种网站中收集、整理所需的信息。这些工具不仅广泛应用于市场研究、竞争情报等商业领域&#xff0c;同时也服务于学术研究、个人兴…

虚函数表和虚函数在内存中的位置

文章目录 结论验证 结论 虚函数表指针是虚函数表所在位置的地址。虚函数表指针属于对象实例。因而通过new出来的对象的虚函数表指针位于堆&#xff0c;声名对象的虚函数表指针位于栈 虚函数表位于只读数据段&#xff08;.rodata&#xff09;&#xff0c;即&#xff1a;C内存模…

量子测量-技术点杂录

目录: 高质量文章导航-持续更新中_GZVIMMY的博客-CSDN博客 前置:量子测量设备 电子显微镜:电子显微镜可以在非常高分辨率下观察生物组织、细胞和分子结构。通过调整电子束的强度和聚焦来观察细胞内部的微小结构。但是,电子显微镜需要对样品进行切片处理,而且在真空中进行…

配置中心--Spring Cloud Config

目录 概述 环境说明 步骤 创建远端git仓库 准备配置文件 配置中心--服务端 配置中心--客户端 配置中心的高可用 配置中心--服务端 配置中心--客户端 消息总线刷新配置 配置中心--服务端 配置中心--客户端 概述 因为微服务架构有很多个服务&#xff0c;手动一个一…

Xilinx FPGA平台DDR3设计详解(二):DDR SDRAM组成与工作过程

本文主要介绍一下DDR SDRAM的基本组成以及工作过程&#xff0c;方便大家更好的理解和掌握DDR的控制与读写。 一、DDR SDRAM的基本组成 1、SDRAM的基本单元 SDRAM的基本单元是一个CMOS晶体管和一个电容组成的电路。 晶体管最上面的一端&#xff0c;称作栅极&#xff0c;通过…

css实现简单的抽奖动画效果和旋转效果,还有春联效果

使用css的animation和transform和transition可以实现简单的图片放大缩小&#xff0c;旋转&#xff0c;位移的效果&#xff0c;由此可以延伸的动画效果还是挺多的&#xff0c;比如图片慢慢放大&#xff0c;图片慢慢旋转并放大&#xff0c;图片慢慢变化位置等等&#xff0c; 抽奖…

mall电商项目(学习记录2)

运行mall-admin Java项目 需要安装Redis&#xff0c;需要安装mysql&#xff0c;同时需要运行其项目提供的mall.sql 运行mall-admin后端程序 安装完Redis、mysql、HeidiSQL&#xff08;用于执行mall.sql&#xff0c;界面化操作高效直观&#xff09;、IntelliJ IDEA 运行mall-…

《算法通关村——原来滑动窗口如此简单》

《算法通关村——原来滑动窗口如此简单》 基本思想 滑动窗口的思想非常简单&#xff0c;如下图所示&#xff0c;假如窗口的大小是3&#xff0c;当不断有新数据来时&#xff0c;我们会维护一个大小为3的一个区间&#xff0c;超过3的就将新的放入老的移走。 这个过程有点像火车…

如何开发互联网医院系统源码?互联网医院小程序开发全流程解析

互联网医院系统源码的开发以及互联网医院小程序的设计是关键环节&#xff0c;本文将为您详细解析开发全流程。 一、需求分析与规划 第一步&#xff0c;明确系统的功能模块。同时&#xff0c;规划系统的整体架构、技术栈&#xff0c;在这里需要想到系统的可扩展性和性能。 二…

千梦网创:熟悉抖音内容创作的切入方式

因为身边抖音网红的资源比较近&#xff0c;所以虽然一直没有露脸去做短视频运营&#xff0c;但是最近也是跟随朋友一起开始了短视频的学习之路。 在参观过一些“超级直播间”之后&#xff0c;我们敲定了未来的两个盈利方向&#xff0c;这两个方向可以将我们身边的资源极致利用…

xxl-job 分布式任务调度框架

文章目录 分布式任务调度XXL-Job 简介XXL-Job 环境搭建XXL-Job (源码说明)配置部署调度中心docker安装 Bean模式任务(方法形式)-入门案例任务详解任务详解-执行器任务详解-基础配置任务详解-调度配置任务详解-基础配置任务详解-阻塞处理策略任务详解-路由策略 路由策略路由策略…

网络和Linux网络_8(传输层)TCP协议_续(流量控制+滑动窗口+拥塞控制+紧急指针+listen第二个参数)

目录 1. 流量控制 2. 滑动窗口 2.1 滑动窗口概念 2.2 滑动窗口模型详解 高速重发控制&#xff08;快重传&#xff09; 3. 拥塞控制和拥塞窗口 4. 延迟应答 5. 捎带应答 6. 面向字节流 7. 粘包问题 8. 16位紧急指针 9. listen的第二个参数 10. TCP总结异常情况与UD…

【上海大学数字逻辑实验报告】三、组合电路(二)

一、实验目的 掌握8421码到余3码的转换。掌握2421码到格雷码的转换。进一步熟悉组合电路的分析和设计方法。学会使用Quartus II设计8421码到余3码的转换电路逻辑图。学会使用Quartus II设计2421码到格雷码的转换电路逻辑图。 二、实验原理 8421码是最常用的BCD码&#xff0c…