以前我使用宏來測量函數調用每當我想快速檢查時所花費的時間。現在,C++提供11,我想最後取出的預處理程序代碼醜陋和平和替換它是這樣的:完美轉發無效和無效返回函數
template <typename Functor, typename ... Args>
auto measure(Functor f, Args && ... args)
-> decltype(f(std::forward<Args>(args)...))
{
auto now = std::chrono::high_resolution_clock::now();
auto ret = f(std::forward<Args>(args)...);
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - now).count();
std::cout << "Time elapsed: " << elapsed << "ms" << std::endl;
return ret;
}
這對於返回的東西(即不void
)功能工作正常。所以我覺得我需要一個void
函數的重載 - 但是你不能在返回類型上重載一個函數。
我試着用一些模板魔法繞過這個問題,但無濟於事;編譯器仍然抱怨說,功能measure
定義兩次:
template <
typename Functor, typename ... Args,
typename ReturnType = typename std::enable_if<
!std::is_void<
typename std::result_of<Functor(Args...)>::type
>::value,
typename std::result_of<Functor(Args...)>::type
>::type
>
ReturnType measure(Functor f, Args && ... args)
{
auto now = std::chrono::high_resolution_clock::now();
auto ret = f(std::forward<Args>(args)...);
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - now).count();
std::cout << "Time elapsed: " << elapsed << "ms" << std::endl;
return ret;
}
template <
typename Functor, typename ... Args,
typename ReturnType = typename std::enable_if<
std::is_void<
typename std::result_of<Functor(Args...)>::type
>::value
>::type
>
ReturnType measure(Functor f, Args && ... args)
{
auto now = std::chrono::high_resolution_clock::now();
f(std::forward<Args>(args)...);
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - now).count();
std::cout << "Time elapsed: " << elapsed << "ms" << std::endl;
}
有沒有辦法解決?
UPDATE
這裏是我現在用的感謝R.費爾南德斯Martinho功能:
template <typename Functor, typename ... Args>
auto measure(Functor f, Args && ... args)
-> decltype(f(std::forward<Args>(args)...))
{
struct scoped_timer
{
scoped_timer() : now_(std::chrono::high_resolution_clock::now()) {}
~scoped_timer()
{
auto elapsed = std::chrono::duration_cast<
std::chrono::milliseconds
>(std::chrono::high_resolution_clock::now() - now_).count();
std::cout << "Time elapsed: " << elapsed << "ms" << std::endl;
}
private:
std::chrono::high_resolution_clock::time_point const now_;
} scoped_timer;
return f(std::forward<Args>(args)...);
}
請參閱http://flamingdangerzone.com/cxx11/2012/06/01/almost-static-if.html#evolution –
高雅[idea](http://stackoverflow.com/a/17748197/1137388)( [R. Martinho Fernandes](http://stackoverflow.com/users/46642/r-martinho-fernandes))。我所做的唯一改變就是將'〜scoped_timer()'的代碼放在一個'try-catch'塊中,以避免拋出任何異常。在語義上,我相信如果不成功完成,不報告'f'運行的時間是有意義的。不幸的是,這對於'<<'拋出的可能異常並不那麼明顯。一個老的'printf'會是一個更好的選擇(關於異常安全)?我不知道。 –