检测继承的函数是否被覆盖
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::*)()
.
如果继承的函数在派生的 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 ofC
, 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::*)()
.