[英]Repeatedly calling a function with a non-type template parameter
I have a function with a non-type template parameter of type int
, like so: 我有一个函数与int
类型的非类型模板参数,如下所示:
template <int N>
int foo() { /*...*/ }
I would like to unit test this function for all values of N
from 0 to 32. I have a function int expected(int n)
that takes the same N
value and returns the expected value. 我想对N
所有值从0到32进行单元测试。我有一个函数int expected(int n)
,它取相同的N
值并返回期望的值。 Effectively, I want: 实际上,我想:
if (foo<0>() != expected(0)) { /* fail... */ }
if (foo<1>() != expected(1)) { /* fail... */ }
if (foo<2>() != expected(2)) { /* fail... */ }
// 30 more lines
I don't want to write out all 33 test cases by hand, and I can't easily use a runtime loop because N
is compile time. 我不想手工写出所有33个测试用例,我不能轻易使用运行时循环,因为N
是编译时间。
How can I get the compiler to generate the test cases for me in a simple way, without BOOST_PP_REPEAT
-style tricks or code generation, in C++11? 在C ++ 11中,如何在没有BOOST_PP_REPEAT
style技巧或代码生成的情况下以简单的方式让编译器为我生成测试用例?
You can write a recursive function template with full specialization to perform the test. 您可以编写具有完全特化的递归函数模板来执行测试。 eg 例如
template <int N>
void test() {
test<N-1>();
if (foo<N>() != expected(N)) { /* fail... */ }
}
template <>
void test<-1>() {
// do nothing
}
and run it like 并运行它
test<32>();
In c++14 you can do something like this 在c ++ 14中,你可以做这样的事情
#include <type_traits>
template <int beg, int end> struct static_for {
template <typename Fn> void operator()(Fn const& fn) const {
if (beg < end) {
fn(std::integral_constant<int, beg>());
static_for<beg + 1, end>()(fn);
}
}
};
template <int n> struct static_for<n, n> {
template <typename Fn> void operator()(Fn const& fn) const {}
};
template <int N> int foo() { /*...*/
return N;
}
int main() {
static_for<0, 32>()([&](auto i) {
if (foo<i>() != i) { /* fail... */
}
});
return 0;
}
Here's a method: 这是一个方法:
template<int N>
void f();
template<int... N>
void g(std::index_sequence<N...>)
{
(f<N>(), ...);
}
Which can be called like so: 可以像这样调用:
g(std::make_index_sequence<33>());
Here's version that actually checks if the tests completed successfully: 这是实际检查测试是否成功完成的版本:
template<int N>
int f();
int expected(int n);
template<int... N>
bool g(std::index_sequence<N...>)
{
return ((f<N>() == expected(N)) && ...);
}
Which is used like: 使用如下:
g(std::make_index_sequence<33>()); // true if all tests are sucessful, false otherwise
A possible C++14 solution, that "simulate" the C++17 template-folding and interrupt the f<N> != expected(N)
at first failure 一种可能的C ++ 14解决方案,它“模拟”C ++ 17模板折叠并在第一次失败时中断f<N> != expected(N)
template <int N>
void f ();
template <int ... Is>
void g (std::integer_sequence<int, Is...>)
{
using unused = int[];
bool ret { false };
(void)unused { 0, (ret ? 0 : (ret = (f<Is>() != expected(Is)), 0))... };
}
callable as follows 可调用如下
g(std::make_integer_sequence<33>());
For a C++11 solution, you need a substitute for std::make_integer_sequence
/ std::integer_sequence
that are available only from C++14. 对于C ++ 11解决方案,您需要替换仅在C ++ 14中可用的std::make_integer_sequence
/ std::integer_sequence
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.