Skip to content

Latest commit

 

History

History
319 lines (208 loc) · 8.14 KB

042.md

File metadata and controls

319 lines (208 loc) · 8.14 KB
layout title
post
第42期

C++ 中文周刊 第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很麻烦,要考虑挺多对齐相关的事儿

视频

介绍std::complex

介绍他们使用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++的,友情推荐一波


本文永久链接