'Accessing element of array of pointers to member functions

I am having some troubles with member function pointers. How do I fix this, and why doesn't this work? The issue is inside main()... or so I am guessing!

#include <iostream>
#include <functional>

template<typename T>
using FnctPtr = void(T::*)(); // pointer to member function returning void

class Base {    
public:
    Base() : vtable_ptr{ &virtual_table[0] } {}
    void foo() {
        std::cout << "Base";
    }
    void x() { 
        std::cout << "X";
    }

 
private:
    // array of pointer to member function returning void
    inline static FnctPtr<Base> virtual_table[2] = { &Base::foo, &Base::x };

public:
    FnctPtr<Base>* vtable_ptr;
};

class Derived : public Base {
public:
    Derived() {
        vtable_ptr = reinterpret_cast<FnctPtr<Base>*>(&virtual_table[0]);
    }
    void foo() /* override */ {
        std::cout << "Derived";
    }

public:
    inline static FnctPtr<Derived> virtual_table[2] = { &Derived::foo, &Base::x };
};

int main() {
    Base* base = new Base();
    base->vtable_ptr[0](); // Issue here
    delete base;
}


Solution 1:[1]

The type of vtable_ptr is void (Base::**)() while the type of base->vtable_ptr[0] is void (Base::*)(). The syntax that you're using for the call is incorrect.

How do I fix this

The correct syntax of using the pointer to member function void (Base::*)() in your example would be as shown below:

(base->*(base->vtable_ptr[0]))();

Note that there was no need for the Derived class in the minimal reproducible example that you've provided.

Working demo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1