I am implementing an RPC system designed to perform tasks in remote processes. One of the nodes of the RPC system is the βMonitorβ, which should record every call.
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; };
It works fine, except in one case where the :: Method result is not valid. To get around this, I had to break the operator () into 2 parts
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; }
Is there a way to eliminate copy-paste, assuming the string is journal("<-", Method::Name()); shouldn't be executed in case of an exception (so I can't wrap the record in a construct / destructor)?
source share