これまで、関数呼び出しが時間を測定するためにマクロを使用していました。何か(すなわちないvoid
)を返す関数のために正常に動作しますvoidとvoid以外の戻り関数のための完全な転送
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;
}
:今、利用できるC++ 11で、私は最終的にプリプロセッサコードの醜い平和を削除して、このようなものと交換したいと思います。だから、私はvoid
関数のオーバーロードが必要だと感じましたが、戻り値の型の関数をオーバーロードすることはできません。
私はいくつかのテンプレートマジックを使ってこの問題を回避しようとしましたが、役に立たなかった。
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;
}
はこれを回避する方法はあります:コンパイラはまだ機能measure
が2回定義されていることを訴えますか?
UPDATE
ここで私は今R.マルティーニ・フェルナンデスへの感謝を使用しています関数です。
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 –
エレガントな[アイデア](http://stackoverflow.com/a/17748197/1137388)( [R. Martinho Fernandes](http://stackoverflow.com/users/46642/r-martinho-fernandes))。私が行う唯一の変更は '〜scoped_timer()'のコードを 'try-catch'ブロックに置くことです。意味的には、 'f'が正常に完了しなければ実行する時間を報告しないと意味があると私は信じています。残念ながら、 '<<"によってスローされる可能性のある例外に関してはそれほど明白ではありません。古い 'printf'が(例外安全性に関して)より良い選択肢になるでしょうか?知りません。 –