我正在实现一个旨在执行远程进程中的任务的RPC系统.RPC系统的一个节点是Monitor,它应该记录每个调用.
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;
};
Run Code Online (Sandbox Code Playgroud)
除了Method :: Result为void之外的一种情况,它工作正常.为了解决这个问题,我不得不将operator()分成两部分
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;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法消除复制粘贴,假设journal("<-", Method::Name());在异常的情况下不应该执行该行(所以我不能在construct /析构函数中包装日志)?
您可以将日志记录封装在 RAII 对象内。只需在析构函数中打印之前检查当前是否有异常正在运行,这可以通过std::uncaught_exception(这将在 C++17 中实现std::uncaught_exceptions)来完成。
如果需要更灵活的东西,您可以使用包装器作为返回值,将其专门用于void:
template <class T>
struct RetWrapper {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args)
: val(std::forward<Tfunc>(func)(std::forward<Targs>(args)...)) {}
T &&value() { return std::move(val); }
private:
T val;
};
template <>
struct RetWrapper<void> {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args) {
std::forward<Tfunc>(func)(std::forward<Targs>(args)...);
}
void value() {}
};
Run Code Online (Sandbox Code Playgroud)
RetWrapper执行函数调用并存储结果,稍后可以通过 移出结果value()。void这与从函数返回 -type 表达式的可能性相关void:
template<typename Method>
typename Method::Result operator()(const Method &method)
{
journal("->", Method::Name());
RetWrapper<typename Method::Result> retVal{transport, method};
journal("<-", Method::Name());
return retVal.value();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |