How to translate this TS Code into modern C 20 using lambdas and modern templating features?
[Edit]: The main question here is: How to restrict typename TFunction
to be of type Function
or even a more specific function with a given signuature?
interface Subscription<TFunction extends Function> {
readonly subscriber: TFunction;
unsubscribe();
}
class Subscriptions<TFunction extends Function = Function> {
private _subscriptions: Subscription<TFunction>[] = [];
subscribe(f: TFunction): Subscription<TFunction> {
// ...
const _subscription: Subscription<TFunction> = {
subscriber: f,
unsubscribe: () => {
this._subscriptions = this._subscriptions.filter(s => s !== f);
};
};
this._subscriptions = [...this._subscriptions, _subscription];
return _subscription;
}
}
CodePudding user response:
Function types in C are expressed as types like R(Arg1, Arg2, Arg3)
(denoting a function that takes three arguments of types Arg1, Arg2, Arg3
and returns an R
). You can take a pointer to such a function, which has the type R(*)(Arg1, Arg2, Arg3)
.
A template will typically use one type parameter for R
and a parameter pack to generalise over all parameter types, e.g. template <typename R, typename... Args> /* something involving the type R(Args...) */
If you want to include objects with appropriate operator()
(especially lambdas), you can use std::function<R(Args...)>
to type erase the specific type of each subscriber.
Something like
template <typename Sig>
struct Subscription
{
std::function<Sig> subscription;
void unsubscribe();
};
template <typename R, typename... Args>
class Subscriptions
{
std::vector<Subscription<R(Args...)>> subscriptions;
public:
R notify(Args... args)
{
R result;
for (auto & s : subscriptions) result = s.subscription(args...);
return result;
}
Subscription<R(Args...)> subscribe(std::function<R(Args...)> s);
};
Because you have to be explicit about object lifetimes in C , lambda captures are more complex, so the implementation of unsubscribe
is going to be tricky, in particular std::function<Sig>
is not equality comparable with itself.