previously using macro measure time function call took whenever wanted check that. now, c++11 available, remove ugly peace of preprocessor code , replace this:
template <typename functor, typename ... args> auto measure(functor f, args && ... args) -> decltype(f(std::forward<args>(args)...)) { auto = 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; } which works fine functions return (i.e. not void). felt needed overload void functions - cannot overload function on return type.
i tried walk around problem using template magic, no avail; compiler still complains function measure defined 2 times:
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 = 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 = 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; } is there way around this?
update
here function using 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)...); }
the problem default template arguments don't make different templates, same way default function arguments don't make different overloads. there ways around this, , described them in remastered enable_if article.
however, not that. take advantage of fact in generic code can "return void", , use raii print out elapsed time:
template <typename functor, typename ... args> auto measure(functor f, args && ... args) -> decltype(f(std::forward<args>(args)...)) { scoped_timer timer; return f(std::forward<args>(args)...); } the scoped_timer class can written trivially: save now in constructor, , compute , output elapsed in destructor.
Comments
Post a Comment