Sto implementando un sistema RPC progettato per eseguire attività nei processi remoti. Un nodo del sistema RPC è Monitor che dovrebbe registrare ogni chiamata.Memorizzare e restituire un tipo generico (anche vuoto) dalla funzione
template<typename Transport, typename Journal>
class Monitor
{
public:
Monitor(Transport transport, Journal &journal) :
transport{std::move(transport)},
journal{journal}
{
}
public:
template<typename Method>
typename Method::Result operator()(const Method &method)
{
Method::Result result;
journal("->", Method::Name());
result = transport(method);
journal("<-", Method::Name());
return result;
}
private:
Transport transport;
Journal &journal;
};
Funziona bene tranne un caso quando Method :: Result è nullo. Per ovviare a questo ho dovuto dividere operatore() in 2 parti
template<typename Transport, typename Journal>
template<typename Method>
std::enable_if_t<std::is_same<typename Method::Result, void>::value, typename Method::Result> operator()(const Method &method)
{
journal("->", Method::Name());
transport(method);
journal("<-", Method::Name());
}
template<typename Transport, typename Journal>
template<typename Method>
std::enable_if_t<!std::is_same<typename Method::Result, void>::value, typename Method::Result> operator()(const Method &method)
{
Method::Result result;
journal("->", Method::Name());
result = transport(method);
journal("<-", Method::Name());
return result;
}
Esiste un modo per eliminare copia-incolla, partendo dal presupposto che la linea journal("<-", Method::Name());
non dovrebbe essere eseguito in caso di un'eccezione (quindi non posso wrap logging in construct/destructor)?
Grazie per il suggerimento. Non ho mai sentito parlare di std :: uncaught_exception prima. L'unico svantaggio è che il controllo viene eseguito in runtime e devo pagare una penalizzazione delle prestazioni – sliser