如下代码为部门首屈一指的高手所写
template<typename T, typename Func, typename... Args>
void execYourFunc(T *t, Func&& f, Args&&... args)
{
auto start = std::chrono::steady_clock::now();
boost::posix_time::ptime now(boost::posix_time::microsec_clock::local_time());
auto ret = std::invoke(f, (args)...);//这一行用得很六,个人非常佩服
auto end = std::chrono::steady_clock::now();
auto consumed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
t->mutable_result()->set_errorcode(std::to_string(ret.value()));
t->mutable_result()->set_consumed_us(consumed);
t->mutable_result()->set_start(boost::posix_time::to_iso_extended_string(now));
t->mutable_result()->set_errormessage(ret.message());
Summary::store(typeid(f).name(), consumed, ret.value());
}
如下为个人画蛇添足
template<typename T, typename Func>
void execYourFuncEx(const std::string &funcName, T *data, Func & func)
{
auto start = std::chrono::steady_clock::now();
boost::posix_time::ptime now(boost::posix_time::microsec_clock::local_time());
auto ret = func();//去掉了变参
auto end = std::chrono::steady_clock::now();
auto consumed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
data->mutable_result()->set_errorcode(std::to_string(ret.value()));
data->mutable_result()->set_consumed_us(consumed);
data->mutable_result()->set_start(boost::posix_time::to_iso_extended_string(now));
Summary::store(funcName, consumed, ret.value());
}
之所以东施效颦,原因在于使用场景,在第一种情况下可能有点复杂, 需要告知Func 具体类型,以便于模板解析。
比如调用 int ProxyA::do_something(int a, int b, int c)
则需要强转方式 static_cast<int(ProxyA::*)(int A, int B, int C)>(&ProxyA::do_something)
execYourFunc(testlibparams->mutable_proxya_do_something(),
static_cast<int(ProxyA::*)(int A, int B, int C)>(&ProxyA::do_something),
&proxyA,
A, B, C);
而个人认为加上强转太复杂,Func以及Func的参数列表,可以自己内部消化
auto innerfunc= [&proxyA, A, B, C]()
{
return proxyA.do_something(A, B, C);
};
execYourFuncEx("your_tool::ProxyA::do_something",
testlibparams->mutable_do_something(),
innerfunc);
上面两种方式各有特点,权当记录,也许以后用得到