在 C++ 中使用模板时如何使用 void 参数
How to use void parameter when using template in C++
我想做一个函数来测试传入函数的运行ning时间。
我使用模板使其适用于许多功能。
我省略了计算时间的代码。
像这样:
template<typename F>
void get_run_time(F func)
{
//time start
func;
//time end
}
但是如果我传入的函数是void
,就会报错提示我添加F=void
。
我试图添加它,但它没有用。我可以把void改成bool,但是很奇怪。
另一个问题是我想正常测试一个函数时间和运行我的整个代码。所以我增加了return值。
像这样:
template<typename F>
F get_run_time(F func)
{
//time start
F tf=func;
//time end
return tf;
}
但是实际测试的时间显然是错误的。我猜它在 return 时开始 运行 函数。如何在继续以下代码之前获得 运行ning 结果?
首先,您需要调用传递的函数来实际计时它的执行时间。请注意,在您的代码中您不调用它,使用 ()
调用运算符:
template <typename Func>
void timer1 (Func func)
{
// start timer
func();
// stop timer
}
其次,注意这些细微差别:
// Will take the same time as the timer1
template <typename Func>
Func timer2 (Func func1)
{
// func2 is a copy of func1
// This copying won't increase the time as you thought it will
Func func2 = func1;
// You still need to call the function
func2();
// Returns pointer to function
return func2;
}
void foo() { std::cout << "foo()" << std::endl; }
int main() {
// Func, here, is a type void (*)()
// Prints "foo()"
timer2(foo);
}
第三,你可能想看看这个方法:
// Since C++14
auto timer3 = [](auto&& func, auto&&... args)
{
// start timer
// Forward the func and invoke the call operator
// with however many forwarded arguments passed to the timer3
std::forward<decltype(func)>(func)(std::forward<decltype(args)>(args)...);
// stop timer
};
void foo(int, int) {}
int main()
{
timer3(foo, 21, 42);
}
如 @JHBonarius, is to use the (since C++17), which was covered in this thread:
所述,以更恰当和简洁的方式完成这项工作
惯用的 C++ 方式(如我所见)是这样
template <class F>
auto call(F f)
{
Timer t;
return f();
}
这适用于返回 void 的函数。注意,这里没有开始和停止。 Timer
是一个 RAII class,它在构建时启动计时器并在销毁时停止。
为简洁起见,未显示 f
的转发参数和 std::invoke
等细节。
我想做一个函数来测试传入函数的运行ning时间。 我使用模板使其适用于许多功能。
我省略了计算时间的代码。 像这样:
template<typename F>
void get_run_time(F func)
{
//time start
func;
//time end
}
但是如果我传入的函数是void
,就会报错提示我添加F=void
。
我试图添加它,但它没有用。我可以把void改成bool,但是很奇怪。
另一个问题是我想正常测试一个函数时间和运行我的整个代码。所以我增加了return值。 像这样:
template<typename F>
F get_run_time(F func)
{
//time start
F tf=func;
//time end
return tf;
}
但是实际测试的时间显然是错误的。我猜它在 return 时开始 运行 函数。如何在继续以下代码之前获得 运行ning 结果?
首先,您需要调用传递的函数来实际计时它的执行时间。请注意,在您的代码中您不调用它,使用 ()
调用运算符:
template <typename Func>
void timer1 (Func func)
{
// start timer
func();
// stop timer
}
其次,注意这些细微差别:
// Will take the same time as the timer1
template <typename Func>
Func timer2 (Func func1)
{
// func2 is a copy of func1
// This copying won't increase the time as you thought it will
Func func2 = func1;
// You still need to call the function
func2();
// Returns pointer to function
return func2;
}
void foo() { std::cout << "foo()" << std::endl; }
int main() {
// Func, here, is a type void (*)()
// Prints "foo()"
timer2(foo);
}
第三,你可能想看看这个方法:
// Since C++14
auto timer3 = [](auto&& func, auto&&... args)
{
// start timer
// Forward the func and invoke the call operator
// with however many forwarded arguments passed to the timer3
std::forward<decltype(func)>(func)(std::forward<decltype(args)>(args)...);
// stop timer
};
void foo(int, int) {}
int main()
{
timer3(foo, 21, 42);
}
如 @JHBonarius, is to use the
惯用的 C++ 方式(如我所见)是这样
template <class F>
auto call(F f)
{
Timer t;
return f();
}
这适用于返回 void 的函数。注意,这里没有开始和停止。 Timer
是一个 RAII class,它在构建时启动计时器并在销毁时停止。
为简洁起见,未显示 f
的转发参数和 std::invoke
等细节。