Коллекция std :: functions с разными аргументами

Я пытаюсь написать простой диспетчер, пользовательский код может прикрепить к нему обратные вызовы. Каждое событие имеет известную подпись, и пользовательский код должен будет вызывать диспетчеризацию с правильным числом и типом аргумента. Это управляется аргументами variadic. Но freestandingInt не принимается, так как вектор имеет неправильный тип. Как сделать это универсальным?

Следует минимальному примеру

void freestanding() {
 std::cout < "freestanding" < std::endl;
}

void freestandingInt(int iArg) {
  std::cout < "freestandingInt " < iArg < std::endl;
}


struct Dispatcher {
 typedef struct Event_ {
   std::vector
 Yakk - Adam Nevraumont02 июн. 2013 г., 16:54
Почему существует только один вид событий? Как другой вопрос, сколько подписей? Можно ли централизовать список? Какие ошибки в рассогласовании аргументов в порядке?
 Alex Darsonik02 июн. 2013 г., 16:56
Тот'неужели у меня нет надежды сохранить только один, я вынужден использовать наследование и сохранять Event * на карте?
 Yakk - Adam Nevraumont02 июн. 2013 г., 17:12
Ваше последнее предложение не имеет смысла для меня. Ошибки компиляции, основанные на предыдущих действиях во время выполнения, невозможны. Я повторю вопрос: почему один диспетчер и один тип мероприятия? Каждое событие может иметь тип, описывающий его сигнатуру, и каждый duspatcher управляет одним списком событий одинакового типа. Диспетчеры могут быть созданы во время компиляции на основе используемых подписей.
 Alex Darsonik02 июн. 2013 г., 17:01
Я хотел бы оставить полную свободу подписи, кроме типа возврата void. Вероятно, должна быть ошибка компилятора при несовпадении аргументов после добавления первой функции в коллекцию слушателей. Я'Лучше не централизовать список, так как я хочу, чтобы События были в иерархии с указателем на родителя.
 Yakk - Adam Nevraumont02 июн. 2013 г., 16:58
Event* бессмысленно. Я хотел бы использовать стирание типа до этого. Если существует более одного события, может также быть более одного диспетчера. Почему бы и нет?

Ответы на вопрос(2)

Дополнительный подход использует std :: bind

void show_text(const string& t)
{
    cout < "TEXT: " < t < endl;
}

std::function 
Решение Вопроса

Вот подход, основанный на созданииstd::multimap отstd::type_index функции кstd::function соответствующего типа:

#include 
#include 
#include 
#include 
#include 

void freestanding() {
  std::cout < "freestanding" < std::endl;
}

void freestandingInt(int iArg) {
  std::cout < "freestandingInt " < iArg < std::endl;
}

// Base class for all functions so that we can store all functions
// in a single container.
struct Function {
  virtual ~Function() { }
};

// Derived class template for functions with a particular signature.
template 
 Alex Darsonik07 июн. 2013 г., 10:31
Я использовал это, и мне действительно это нравится. Это'Также очень хороший пример использования multimap с type_index, спасибо
 T.C.10 сент. 2015 г., 07:17
Как минимум,Function нужен виртуальный деструктор. И сама идея восстановления типа функции по типу аргумента, когда аргументы берутся путем перенаправления ссылки, имеет очень мало смысла. В качестве простого примера, этот код разбивается на.int i = 0; disp.dispatch(0, i);
 Vaughn Cato10 сент. 2015 г., 09:10
@ T.C .: Оба хороших момента. Я'Мы добавили виртуальный деструктор. Я также изменил код для использованияstd::remove_reference чтобы справиться с делом, которое вы упомянули, хотя есть много других дел, которые все же выигралит работа. Заставить его обрабатывать разрешение перегрузки, эквивалентное стандартным правилам, было бы довольно сложно.

Ваш ответ на вопрос