这个讲的是scope_exit, std::range, make_range , operator <=> ,后面这两个已经进入c++标准了,前面这个有很多案例

先说scope_exit

作者写了个宏,显得scope_exit更好用一些,实际上没啥必要

他的实现类似这个

 template <typename Callable> class scope_exit {
   Callable ExitFunction;
   bool Engaged = true; // False once moved-from or release()d.
 
 public:
   template <typename Fp>
   explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
 
   scope_exit(scope_exit &&Rhs)
       : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
     Rhs.release();
   }
   scope_exit(const scope_exit &) = delete;
   scope_exit &operator=(scope_exit &&) = delete;
   scope_exit &operator=(const scope_exit &) = delete;
 
   void release() { Engaged = false; }
 
   ~scope_exit() {
     if (Engaged)
       ExitFunction();
   }
 };
 

几个疑问

  • 为什么直接保存Callable,而不是用 std::function来保存
    • 太重,引入类型擦除,效率不行,生成的汇编很差
    • 作者还稍稍科普了下类型擦除的技术,怎么做到的
  • 为什么不用AA的scopeguard或者boost::scope_exit
    • 不好用,还需要传参数,scope_exit好就好在可以传lambda

第二个是make_iterable,对应标准库应该是std::range 本质上还是视图一类的东西。因为自定义类型,不想写一套iterator接口,给个view就行。没啥说的

第三个是operator<=> 实际上是解决comparator这种语义实现的问题

就比如rocksdb,bytewisecomparator

  int r = memcmp(data_, b.data_, min_len);
  if (r == 0) {
    if (size_ < b.size_) r = -1;
    else if (size_ > b.size_) r = +1;
  }
  return r;

内部肯定有三个分支,这是影响效率的,怎么搞?

再比如std::tuple 他是怎么比较的?

然后推导出一个适当的operator<=>来解决上述问题

ref