author avatar

Liu Bang

总共 52 篇文章

前言

c++11 对智能指针做了很大的优化,废弃了 c++98 中的auto_ptr,引入了三种新的智能指针:unique_ptrshared_ptrweak_ptr。 本文将针对unique_ptr的一些使用技巧做一些整理和归纳。在正式开始之前,我们首先来回顾一下unique_ptr的特点:一个unique_ptr对象内包含一个原始指针,该unique_ptr对象负责管理原始指针的生命周期。 一个unique_ptr对象始终是其关联的原始指针的唯一拥有者。

在了解了unique_ptr的特点之后,我们来具体看看日常开发中unique_ptr的一些使用场景和技巧。

一些场景

本地对象指针

在开发中,我们经常会遇到或者写出类...

什么是 Expression Templates

Expression Templates 是一种 C++ 模板元编程技术,它通过在编译时构建按需执行的计算表达式,从而生成高效的代码。简单来说,通过 Expression Templates,我们可以实现惰性求值和消除因为中间结果而创建的临时变量。

一个常规示例

我们构造了一个MyVector类,并且重载了MyVector+*操作符,实现两个MyVector中相同下标元素的+*操作。 对于这样的需求我们很容易写出形如下面代码的一个简单的实现:

#include <cassert>
#include <iostream>
#include...

动态多态 (Dynamic Polymorphism)

在 c++中为了实现多态,使用了一种动态绑定的技术,这个技术的核心就是虚函数表(virtual table)。下面就简单的说明一下基于虚表的动态绑定的原理,从而更好的与静态多态做比较。

在 c++中,每个包含虚函数的类都有一个虚表。我们来看下面这个类:

// demo.cpp
class A
{
public:
    virtual void vfunc1();
    virtual void vfunc2();
    void         func1();
    void         func2();

private:
    int m_data1,...

constexpr 是 c++11 引入的关键字,用于编译时常量和常量表达式。而 c++17 将这一特性做了增强,引入了 constexpr if , 使得编译器在编译时(compile time)能够做分支判断,从而有条件的编译代码。

下面可以通过一个简单的例子来看看constexpr if的用法:

#include <iostream>
#include <type_traits>

template<typename T> auto getValue(T t)
{
    if constexpr (std::is_pointer<T>::value) {...

对于熟悉 c99 的人来说,Designated Initializers 并不算是什么新鲜事物,然而 c++直到 c++20 才正式支持这一特性。 虽然在 c++20 之前,像 GCC 这样的编译器通过扩展的形式已经对该特性做了支持,但是随着 c++20 将其纳入新标准,这一特性将在所有编译器中得到支持。

基本用法

Designated Initialization 是聚合初始化(Aggregate Initialization)的一种形式。 在 c++20 中,聚合类型(Aggregate types)是指:

  • 数组类型
  • 具备如下特性的 class 类型:
    • has no private or protected...

对于一个标准的 c++容器来说,我们可以很容易在运行时使用迭代器和 range-based for loop 来遍历其中的每一个元素。但是对于std::tuple,却不能像普通的容器那样去遍历它。

std::tuple 简介

std::tuple是一个具有固定大小,包含不同类型值的集和。与之相似的是std::pair,只不过std::pair只能容纳两个元素, 而std::tuple可以容纳许多元素:

std::tuple<int, double, const char*> tup {42, 10.5, "hello"};

// or with CTAD(class template argument...

string_view 简介

std::string_view是 c++17 中新增的一种类型。其核心理念是,能够让我们在传统的 C++03 风格的具体性和泛型编程之间找到一个很好的折衷点。 在 C++17 标准之前,我们通常只能在粗糙的不严谨的模板实现和相对严谨但是有着冗长约束的模板之间做出选择。举个简单的例子:

// c++03 style
class Widget
{
    std::string name_;

public:
    void setName(const char* new_name);
    void setName(const std::string& new_name);
};

// ...

1. 概览

要谈论 LevelDB 的 Compaction 就不得不从 LevelDB 的整个数据写入流程入手。LevelDB 的基本写入流程大致为:

  1. 数据先写入到 WAL 日志中,做持久化
  2. 然后数据同步到mutable memtable
  3. mutable memtable大小达到Options.write_buffer_size设置的大小时,就会变成immutable memtable,并且创建一个新的mutable memtable
  4. 后台的 Compaction 线程会把immutable memtabledump 成 sstable 文件,并设置于 Level 0 层
  5. 当 Level i 达到一定条件后,...

使用 c 语言的 macro 操作,能够很简单的用 c 语言模拟 lisp 语法。

下面我们来定义 lisp.h 头文件

#ifndef LISP_H_OTE1HWPK
#define LISP_H_OTE1HWPK

#include <stdio.h>
#include <stdlib.h>

#define define(ret, name, args, block) \
    ret name args { return block; }

#define if(expr, block1, block2) \
    expr ? block1 : block2

#define eq(a, b)...