#include <functional>
#include <iterator>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <typeinfo>
#include <array>

std::vector<std::pair<std::function<void(int)>, void*>> callbacks;

class MyClass{
  static unsigned const num_possible_callbacks = 2; // keep updated
  std::array<std::type_info const*, num_possible_callbacks> _infos;
  unsigned _next_info;

  // adds type_info and passes through
  template<class T>
  T const& add_info(T const& bound){
    if(_next_info == num_possible_callbacks)
      throw "oh shi...!"; // something went out of sync
    _infos[_next_info++] = &typeid(T);
    return bound;
  }
public:
  MyClass() : _next_info(0){
    using std::placeholders::_1;
    callbacks.push_back(std::make_pair(
        add_info(std::bind(&MyClass::myFunc, this, _1)),
        (void*)this));
    callbacks.push_back(std::make_pair(
        add_info([this](int i){ return myOtherFunc(i, 0.5); }),
        (void*)this));
  }

  ~MyClass(){
    using std::placeholders::_1;

    callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(),
        [&](std::pair<std::function<void(int)>, void*> const& p) -> bool{
          if(p.second != (void*)this)
            return false;
          auto const& f = p.first;
          for(unsigned i = 0; i < _infos.size(); ++i)
            if(_infos[i] == &f.target_type())
              return true;
          return false;
        }), callbacks.end());
  }

  void myFunc(int param){ /* ... */ }
  void myOtherFunc(int param1, double param2){ /* ... */ }
};

int main(){
  auto print = []{ std::cout << "Callbacks:" << callbacks.size() << "\n"; };
  print();
  {
    MyClass c1;
    print();
    {
      MyClass c2;
      print();
    }
    print();
  }
  print();
}