以前は、マクロを使用して関数呼び出しにかかった時間を測定し、すぐに確認したかったのです。今、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
が 2 回定義されているとまだ不平を言っています。
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;
}
これを回避する方法はありますか?
アップデート
R. Martinho Fernandes のおかげで、私が現在使用している関数は次のとおりです。
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)...);
}