#include <iostream>


// The essence

namespace essence {
template<class Ptr, size_t Id>
Ptr result;

template<class Ptr, Ptr TargetPointer, size_t InstantiationId>
struct steal {
    struct exec_on_instantiation {
        exec_on_instantiation() { 
            result<Ptr, InstantiationId> = TargetPointer;
        }
    };
    static exec_on_instantiation essence;
};
template <typename Ptr, Ptr TargetPointer, size_t InstantiationId>
typename steal<
    Ptr, 
    TargetPointer, 
    InstantiationId
>::exec_on_instantiation steal<
    Ptr, 
    TargetPointer, 
    InstantiationId
>::essence;
}  // namespace essence


// Demo

using std::string;
using std::cout;
using std::endl;

class Victim {
    void f() { cout << "PoC - member function f" << endl; }
    void h() { cout << "PoC - member function h" << endl; }
    string str = "PoC - member data";
    static void g() { cout << "PoC - static member function" << endl; }
    static string static_str;
};
string Victim::static_str = "PoC - static member data";

template struct essence::steal<decltype(&Victim::f), &Victim::f, 1>;
template struct essence::steal<decltype(&Victim::h), &Victim::h, 2>;
template struct essence::steal<decltype(&Victim::str), &Victim::str, 3>;
template struct essence::steal<decltype(&Victim::g), &Victim::g, 4>;
template struct essence::steal<
    decltype(&Victim::static_str), 
    &Victim::static_str, 
    5
>;

int main() {
    auto ptr1 = essence::result<void (Victim::*)(), 1>;
    auto ptr2 = essence::result<void (Victim::*)(), 2>;
    auto ptr3 = essence::result<string (Victim::*), 3>;
    auto ptr4 = essence::result<void(*)(), 4>;
    auto ptr5 = essence::result<string*, 5>;
    
    Victim a;
    
    (a.*ptr1)();
    (a.*ptr2)();
    a.*ptr3 += " (modified)", cout << a.*ptr3 << endl;
    ptr4();
    *ptr5 += " (modified)", cout << *ptr5 << endl;
}