Skip to content
败犬日报 2026-01-12

败犬日报 2026-01-12

1. 编译期检查类的一些字段非空

一般来说可以用构造函数传递所有字段,从而保证非空。群友给了 builder + 模板的办法,不知道实用性如何:

cpp
struct A {
    int x;
    double y;
    std::string z;
};

template <bool is_set_x = false, bool is_set_y = false, bool is_set_z = false>
struct A_Builder {
    static A_Builder<false, false, false> create() {
        return A_Builder<false, false, false>();
    }

    A_Builder<true, is_set_y, is_set_z> set_x(int x) {
        a_.x = x;
        A_Builder<true, is_set_y, is_set_z> rhs;
        rhs.a_ = a_;
        return rhs;
    }

    A_Builder<is_set_x, true, is_set_z> set_y(double y) {
        a_.y = y;
        A_Builder<is_set_x, true, is_set_z> rhs;
        rhs.a_ = a_;
        return rhs;
    }

    A_Builder<is_set_x, is_set_y, true> set_z(const std::string& z) {
        a_.z = z;
        A_Builder<is_set_x, is_set_y, true> rhs;
        rhs.a_ = a_;
        return rhs;
    }

    A build() {
        static_assert(is_set_x, "Field x is not set");
        static_assert(is_set_y, "Field y is not set");
        static_assert(is_set_z, "Field z is not set");
        return a_;
    }

   private:
    template <bool Sx, bool Sy, bool Sz>
    friend class A_Builder;
    A a_;
};

int main() {
    A a =
        A_Builder<>::create().set_x(42).set_y(3.14).set_z("Hello").build();

    std::cout << "A.x: " << a.x << ", A.y: " << a.y << ", A.z: " << a.z
                << std::endl;
    // A b = A_Builder<>::create()
    //           .set_x(42)
    //           .set_y(3.14)
    //           .build();
}

也可以实现 required<T>,然后用聚合初始化:

cpp
template <typename T>
struct required {
    T data;
    template <typename U>
    required(U&& data) : data(data) {}
};

struct A {
    int x;
    double y;
    std::string z;
};

struct A_Builder {
    required<int> x;
    required<double> y;
    required<std::string> z;

    A build() {
        return A{std::move(x.data), std::move(y.data), std::move(z.data)};
    }
};

int main() {
    {
        A a = A_Builder{.x = 42, .y = 3.14, .z = "Hello"}.build();

        std::cout << "A.x: " << a.x << ", A.y: " << a.y << ", A.z: " << a.z
                  << std::endl;
    }
    {
        // A a = A_Builder{.y = 3.14, .z = "Hello"}.build();
    }
    return 0;
}

2. IPADS新人培训第二讲:CMake(视频)

https://www.bilibili.com/video/BV14h41187FZ