【发布时间】:2016-03-23 03:46:38
【问题描述】:
一些通用代码操作函数,需要根据函数是否有返回值来进行不同的操作。例如,借用this question 的一个问题,假设我们需要编写一个time_it 函数,接受一个函数和一些参数,运行它,并打印经过的时间。下面的代码可以做到这一点:
#include <chrono>
#include <type_traits>
#include <cmath>
#include <iostream>
template<class Fn, typename ...Args>
auto time_it(Fn fn, Args &&...args) ->
typename std::enable_if<
!std::is_void<typename std::result_of<Fn(decltype(std::forward<Args>(args))...)>::type>::value,
typename std::result_of<Fn(decltype(std::forward<Args>(args))...)>::type>::type
{
const auto start = std::chrono::system_clock::now();
auto const res = fn(std::forward<Args>(args)...);
const auto end = std::chrono::system_clock::now();
std::cout << "elapsed " << (end - start).count() << std::endl;
return res;
}
template<class Fn, typename ...Args>
auto time_it(Fn fn, Args &&...args) ->
typename std::enable_if<
std::is_void<typename std::result_of<Fn(decltype(std::forward<Args>(args))...)>::type>::value,
void>::type
{
const auto start = std::chrono::system_clock::now();
fn(std::forward<Args>(args)...);
const auto end = std::chrono::system_clock::now();
std::cout << "elapsed " << (end - start).count() << std::endl;
}
int main()
{
time_it([](double x){return std::cos(x);}, 3.0);
time_it([](double x){}, 3.0);
}
可以看出,函数返回值与否的情况是有区别的。在前一种情况下,必须存储值,打印经过的时间,并返回值;在后一种情况下,打印经过的时间后,无需进行任何其他操作。
问题是如何处理这两种情况:
-
1234563尤其是身体的大部分重复。
上述答案绕过了该问题,方法是将经过的时间打印为调用某个经过的计时器类的析构函数的副产品。这是个好主意,但在更复杂的用途中会导致代码复杂(大量工作是在某个单独类的析构函数中完成的 - 这不是自然流程)。
有更好的方法吗?
【问题讨论】:
标签: c++ c++11 void sfinae result-of