Search code examples
c++function-pointersstatic-assert

How to statically check if two functions that might or might not have the same signature are the same function?


I want to statically check whether two functions are the same one.

Something like this:

struct Base { void f(){} };
struct Derived1: public Base { void f(){ puts("Hey!"); } };
struct Derived2: public Base { int f(){ return 0; } };
struct Derived3: public Base {};

static_assert( &Base::f != &Derived1::f );
static_assert( &Base::f != &Derived2::f );
static_assert( &Base::f == &Derived3::f );

The second static_assert fails to compile because the signature of Base::f and Derived2::f differs:

error: comparison of distinct pointer types ('void (Base::*)()' and 'int (Derived2::*)()')
static_assert( &Base::f != &Derived2::f );
               ~~~~~~~~ ^  ~~~~~~~~~~~~

I tried to static_cast those function pointers to void*, unitptr_t or void(Base::*)(), but the compiler won't let me. While the result of reinterpret_cast is not static and can't appear in a static_assert.

How can I perform the check?

Any C++ standard is fine.


Solution

  • You need something to reject the different signatures before trying to == them.

    template <typename F1, typename F2>
    constexpr bool same_function(F1, F2) { return false; }
    
    template <typename F>
    constexpr bool same_function(F f1, F f2) { return f1 == f2; }
    

    See it live