一、std::clamp()
其实在前面简单介绍过这个函数,但当时只是一个集中的说明,为了更好的理解std::clamp的应用,本篇再详细进行阐述一次。std::clamp在C++17中其定义的方式为:
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
template< class T, class Compare >
constexpr const T& clamp( const T& v, const T& lo, const T& hi,
Compare comp );
说明文档中表明其使用“<”(c++20后使用less,所以T必须可<运算,否则未定义)或自定义comp来实现。无论使用哪种实现,其结果都是返回v(lo~hi范围内)或返回边界值(接近于v的lo或 hi)的引用。注意,如果lo和hi不可比较,则行为未定义。最简单的就是lo>hi,行为即未定义。
二、应用
std::clamp的出现,解决了一个很常见的问题,就是判断范围。这个功能说大不大,但用处非常多,比较在实际中判断电压、电流的值,判断亮度的值,判断数值的域等等,太多了。如果不使用它,就需要自己用if语句来搞定,没有难度,就是少写多写几行代码的事儿。
#include <algorithm>
#include <iostream>
constexpr int HI = 1200;
constexpr int LO = 1;
struct Worker{
int id = 0;
bool operator < (const Worker&w)const{
return id < w.id;
}
};
int CompFun(const Worker&w1,const Worker&w2){
return w1.id < w2.id;
}
int main()
{
int v = 16;
std::clamp(v, LO, HI);
Worker loW {LO};
Worker hiW {HI};
Worker p1;
p1.id = 10;
std::cout<<"use compare func clamp value:"<< std::clamp(p1, loW, hiW,CompFun).id<<std::endl;
Worker p2;
p2.id = 11;
std::cout<<" clamp value:"<< std::clamp(p2,loW,hiW).id<<std::endl;
//std::cout<<" clamp value:"<< std::clamp(p2,hiW,loW).id<<std::endl;
return 0;
}
大家可以猜一下,注释部分的结果,再和说明比较即可明白。
三、分析说明
虽然std::clamp方便简单,但在实践应用中,还是需要和实际场景结合,建议如下:
1、基础类型的判断处理可以转移到此函数中
2、复杂的比较要看情况,不一定非为了使用它搞一个小于运算符的重载
std::clamp之所以表现比较好,主要原因是其内联调用相关函数,对一些比较在底层进行了优化(包括编译优化和CPU优化等)。
不过从实际的经验来看,std::clamp对提高效率并不是太大,所以不需要盲目的应用特别是改写以前的比较代码。但在一些比较重视效率或控制代码的简洁程度上还是有很好的作用。
四、总结
AI在发展,库也在发展,会不会到最后,大家只要碎碎念一下,一个程序就出来?这种不是没有可能。但是这种可能,大概率可能需要相当长的时间。其实如果真到了那个地步,为什么还要写程序?机器人自己就搞定自己了。人类就享受一切即可。
不过到那时,可能大多数人活得更不如意!