Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if inherited function is overridden

I came up with the following code detecting at compile time if inherited functions are overridden in the derived class. It works with all major compilers - gcc/clang/msvc. But is this approach actually backed by the standard?

#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;
}
like image 775
amosk Avatar asked Jan 04 '21 16:01

amosk


People also ask

How do you check if a method is overridden?

getMethod("myMethod"). getDeclaringClass(); If the class that's returned is your own, then it's not overridden; if it's something else, that subclass has overridden it.

Are overridden methods inherited?

Overridden methods are not inherited.

What is function overriding in inheritance?

When the base class and derived class have member functions with exactly the same name, same return-type, and same arguments list, then it is said to be function overriding.

How can you prevent a function from being overridden?

In C++, there's no way to forbid it, it's just that by definition of "override", only virtual functions can be "overridden".


Video Answer


1 Answers

Found it, this is covered by by section 20.15.9 Member relationships, point 5 of the standard:

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.

Given example:

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 ));

And so on and so forth. That explain why in your example, &B::f2 and &D::f2 as well as &B::f4 and &D::f4 have the same type void(B::*)().

like image 189
Peter Avatar answered Oct 22 '22 20:10

Peter