Простым решением является использование типов тегов, таких как
struct EmployeeID_T {};
struct FavoriteNumber_T {};
и привязка типа аргумента к имени, например
using EmployeeID = SignalArg<EmployeeID_T, int>;
using FavoriteNumber = SignalArg<FavoriteNumber_T, double>
, чтобы вы получили
Signal<EmployeeID, FavoriteNumber> mySignal;
signal.add(BLOCK, [](EmployeeID eid, FavoriteNumber fn) {
std::cout << EmployeeNames[eid]
<< " has favorite number of "
<< fn << std::endl;
});
signal.add(BLOCK, [](EmployeeID eid, FavoriteNumber fn) {
if (eid > fn) {
std::cout << EmployeeNames[eid]
<< " has ID bigger than favorite number.\n";
}
});
mySignal(5, 3.1415); //execute both functors with args = (5, 3.1415)
Вам необходим шаблон SignalArg
с соответствующими конструкторами и операторами преобразования, но, поскольку я его не записал, может потребоваться некоторое принуждение.
Типы тегов предотвращают неявное преобразование между различными аргументами с помощьютот же базовый тип, который позволял бы использовать только typedef.
Вы также можете получить что-то вроде именованных параметров, сделав явным конструктор преобразования SignalArg, поэтому вместо этого вызов будет выглядеть примерно так:
mySignal(EmployeeID{5}, FavoriteNumber{3.1415});