layout | title |
---|---|
post |
第42期 |
从reddit/hackernews/lobsters摘抄一些c++动态
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
更快的tolower(仅限ascii)你学费了吗
编译器信息最新动态推荐关注hellogcc公众号 本周更新 OSDT Weekly 2021-12-15 第128期
另外,咱们文章也会贴到hellogcc公众号发布通知
值得一看,介绍了很多边角优化点。其中无符号判断empty和pointer alias这些我们在之前介绍过。值得再看
bug的代码长这样
void AdSort(std::vector<AdItem> &ad_items) {
std::sort(ad_items.begin(), ad_items.end(), [](const AdItem &item1, const AdItem &item2) {
if (item1.priority < item2.priority) {
return true;
} else if (item1.priority > item2.priority) {
return false;
}
return item1.score >= item2.score;
} );
}
注意比较要求严格弱序,所以这里的lambda实现有问题
等于应该返回false
这个问题其实算是老生常谈了,搜std::sort coredump能搜到好几个std::sort代码走读/科普严格弱序啥意思的文章。这里就不啰嗦了
这些年来c++ lambda的变化
c++14
//默认值
auto myLambda1 = [](int x, int y = 0){ std::cout << x << '-' << y << '\n'; };
// 自动推导参数(残废的模版)
auto myLambda = [](auto&& x){ std::cout << x << '\n'; };
//返回一个lambda
auto getMyLambda(int z)
{
return [z](int x)
{
// ...
// ...
// ...
};
}
void f()
{
// ...
int z = 42;
auto myLambda = getMyLambda(z);
// ...
}
c++ 17
constexpr auto times2 = [] (int n) { return n * 2; };
//拷贝this
struct MyType
{
int m_value;
auto getLambda()
{
return [self = *this](){ return self.m_value; };
}
};
c++20
// 模版
auto myLambda = []<typename T>(T&& value){ std::cout << value << '\n'; };
//变参模版
template<typename... Ts>
void f(Ts&&... args)
{
auto myLambda = [...args = std::forward<Ts>(args)](){};
}
这个提案看个乐,未必能过
template <class T> auto to_string() {
const auto t = get_aliased(mirror(T));
std::stringstream str{};
str << get_name(t) << '{';
for_each(get_enumerators(t),
[&str](auto o) { str << get_name(o) << '=' << get_constant(o) << ';'; }
);
str << '}';
return str.str();
}
enum Weekdays {
Mon = 2,
Tue = 3,
Wed = 4,
Thu = 5,
Fri = 6,
Sat = 1,
Sun = 0
};
int main() {
std::cout << to_string<Weekdays>(); // prints Weekdays{Mon=2;Tue=3;Wed=4;Thu=5;Fri=6;Sat=1;Sun=0;}
}
通过这个小工具可以轻松写出自己的allocator的aligned_alloc接口
面向的需求是,自定义的一个分配器(比如固定的buffer cache,构造/析构 不释放)可能需要提供alloc还有aligned_alloc
而aligned_alloc很麻烦,要考虑挺多对齐相关的事儿
介绍他们使用range的经验,实践就是干掉所有for循环,能用range的用range替代
这个大爷的口音真的很让人犯困,但是这个问题可能很多人没注意 min max 在等于的场景下的语意很模糊
一个简单的实现
template<typename T>
const T& min(const T& a, const T& b) {
return a < b ? a : b;
}
template<typename T>
const T& max(const T& a, const T& b) {
return a > b ? a : b;
}
如果a等于b ,返回的是b
也许你会说,这又咋了,返回a 返回b有啥区别呢?简单int之类scalar type的确实没啥区别
给个例子
struct student {
std::string name;
int id;
inline static int regist = 0;
student(std::string n) : name(n), id(regist++) {}
bool operator <(student s) const {
return name < s.name;
}
}
如果比较student 哪个小 明明student a b 的id绝对是不同的,但是永远返回了b,区分不清 a b的场景,
那如果求最大值,是不是应该返回a,这样才能区分
这就是这个两个接口的问题
行为要互补
另外,需要对比较的对象做一个约束(concept)一直递增,这样就能更好的描述这两个接口
所以实现就这个样子
inline bool out_of_order(... a, ... b) { return b<a;}
template<typename T>
const T& min(const T& a, const T& b) {
return out_of_order(a, b) ? b : a;
}
template<typename T>
const T& max(const T& a, const T& b) {
return out_of_order(a, b) ? a : b;
}
引申一下,这个约束叫啥呢?严格全序? 引入std::range::less
这个视频非常值得一看,把compare讲的明明白白
- parlaylib并行算法工具箱
- mold 发布正式版1.0,之前我们介绍过,是一个非常牛的 linker,速度快
- cpp-rrb 一个RRB-tree实现,尽管 immer.库有个类似的immer::flex_vector
- TLM 一个检测线程死锁的库
一个简单例子
#include "thread_monitor/thread_monitor.h"
void myLivelockedMethod();
void myParentMethod() {
thread_monitor::ThreadMonitor<> monitor("Livelock demo", 1);
std::this_thread::sleep_for(2ms);
thread_monitor::threadMonitorCheckpoint(2);
myLivelockedMethod();
}
void myLivelockedMethod() {
thread_monitor::threadMonitorCheckpoint(3);
while (true) {
std::this_thread::sleep_for(1ms);
}
}
明显的死循环,过一段时间,monitor就会吧这个打印出来
Frozen thread: Livelock demo id: 140085845083904
Checkpoint: 1 at: 2021-12-09 23:29:36.201542 delta: 0 us
Checkpoint: 2 at: 2021-12-09 23:29:36.203625 delta: 2083 us
原理就是有个队列记录状态,状态长时间不更新就打印
如果你把thread_monitor::threadMonitorCheckpoint(4);
放到while循环内部,就永远不会触发frozen打印
用来做个debug还是够用的
将ldd的显示列成tree的形式
这俩招聘暂时放一个月。主要是没新的
昆仑数据库,魔改mysql的,还支持远程工作,友情推荐一波
现在mysql的代码已经很现代c++了
开发深度学习编译器,而且他们也支持远程工作,c++的,友情推荐一波