检测继承的函数是否被覆盖

Detect if inherited function is overridden

如果继承的函数在派生的 class 中被覆盖,我想出了以下代码在编译时检测。它适用于所有主要编译器 - gcc/clang/msvc。 但是这种方法真的有标准支持吗?

#include <type_traits>

struct B {
    virtual void f1() {}
    virtual void f2() {}
    void f3() {}
    void f4() {}
};

struct D: B {
    void f1() override {}
    void f3() {}
};

int main()
{
    static_assert(!std::is_same_v<decltype(&B::f1), decltype(&D::f1)>, "overriden");
    static_assert(std::is_same_v<decltype(&B::f2), decltype(&D::f2)>, "base");
    static_assert(!std::is_same_v<decltype(&B::f3), decltype(&D::f3)>, "overriden");
    static_assert(std::is_same_v<decltype(&B::f4), decltype(&D::f4)>, "base");
    return 0;
}

找到了,这在标准的第 20.15.9 Member relationships 节中涵盖:

Note: The type of a pointer-to-member expression &C::b is not always a pointer to member of C, leading to potentially surprising results when using these functions in conjunction with inheritance.

举个例子:

struct A { int a; };
struct B { int b; };
struct C: public A, public B { };

// The following will succeed because, despite its appearance,
// &C::b has type "pointer to member of B of type int"
static_assert(is_pointer_interconvertible_with_class( &C::b ));

等等等等。这解释了为什么在您的示例中,&B::f2&D::f2 以及 &B::f4&D::f4 具有相同的类型 void(B::*)().