Skip to content
败犬日报 2026-04-13

败犬日报 2026-04-13

1. C++20 如何判断一个类 override 某个函数

可以用成员函数指针来做。(虽然这个需求有点奇怪)

cpp
#include <type_traits>

struct Base {
    virtual void foo(int x);
    virtual void foo(double x);
    virtual void bar();
    void baz(int x);
};

// 正确思路:反向检测,看 &T::foo 能否隐式赋给 void(Base::*)(int)
//
// 标准规定:void(Base::*)(int) → void(Derived::*)(int) 是隐式转换(Base→Derived 方向)
//          void(Derived::*)(int) → void(Base::*)(int) 需要显式 cast(Derived→Base 方向)
//
// 因此:
//   若 T 未 override foo:&T::foo 自然是 void(Base::*)(int),赋给 void(Base::*)(int) 成功
//   若 T 已 override foo:&T::foo 是 void(T::*)(int),Derived→Base 需要显式 cast,赋值失败
//
// is_override = !能隐式赋给void(Base::*)(int)
//
// 注意:不能用 lambda 包裹,lambda body 里的类型错误是 hard error 而非 SFINAE。
// 使用 parametric requires-expression: requires(T param) { expr } 才能正确做 SFINAE。

template <typename T>
constexpr bool is_override_function_foo = requires {
    requires std::is_base_of_v<Base, T>;
    requires !requires(void (Base::*p)(int)) { p = &T::foo; };
};

template <typename T>
constexpr bool is_override_function_baz = requires {
    requires std::is_base_of_v<Base, T>;
    requires !requires(void (Base::*p)(int)) { p = &T::baz; };
};

// ---- 测试 ----
struct Derived1 : Base {
    void foo(int x) override {}
    void baz(int x) {}
};

struct Derived2 : Base {};

static_assert( is_override_function_foo<Derived1>);
static_assert(!is_override_function_foo<Derived2>);
static_assert(!is_override_function_foo<Base>);
static_assert( is_override_function_baz<Derived1>);
static_assert(!is_override_function_baz<Derived2>);

int main() {}

2. 从ClickHouse的60个哈希表模板的Switch Case到Variant再到CRTP(文章)

https://zhuanlan.zhihu.com/p/2026689745665705434