前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 动态新闻推送 第42期

C++ 动态新闻推送 第42期

作者头像
王很水
发布2021-12-18 12:12:33
2750
发布2021-12-18 12:12:33
举报

文章

值得一看,介绍了很多边角优化点。其中无符号判断empty和pointer alias这些我们在之前介绍过。值得再看

bug的代码长这样

代码语言:javascript
复制
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

代码语言:javascript
复制
//默认值
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

代码语言:javascript
复制
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

代码语言:javascript
复制
// 模版
auto myLambda = []<typename T>(T&& value){ std::cout << value << '\n'; };

//变参模版
template<typename... Ts>
void f(Ts&&... args)
{
    auto myLambda = [...args = std::forward<Ts>(args)](){};
}

这个提案看个乐,未必能过

代码语言:javascript
复制
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 在等于的场景下的语意很模糊

一个简单的实现

代码语言:javascript
复制
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的确实没啥区别

给个例子

代码语言:javascript
复制
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)一直递增,这样就能更好的描述这两个接口

所以实现就这个样子

代码语言:javascript
复制
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 一个检测线程死锁的库

一个简单例子

代码语言:javascript
复制
#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就会吧这个打印出来

代码语言:javascript
复制
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的形式

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章
  • 视频
  • 项目
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档