是否有简明的方法指向模板化函数的所有实例而不使用宏?
我有几个模板化的函数,我想测试各种类型:
template<typename T>
void function1() {
return;
}
template<typename T>
void function2() {
return;
}
template<typename T>
void function3() {
return;
}
我可以用宏来做到这一点:
#define TEST_ACROSS_TYPES(fn) \
fn<int>(); \
fn<bool>(); \
fn<char>(); \
fn<double>(); \
TEST_ACROSS_TYPES(function1);
TEST_ACROSS_TYPES(function2);
但是,(1)宏很丑,很难让其他人遵循,(2)我使用的是CATCH
,当使用宏设置测试用例时,它并不好玩
有没有办法做这样的事情:
void testAcrossTypes(SomeType f) {
f<int> ();
f<bool> ();
f<char> ();
f<double> ();
}
除了定义SomeType
的问题外,似乎更清晰。这个问题(How to define typedef of function pointer which has template arguments)解释了如何定义指向模板化函数的指针;但是,要求指定模板参数。
澄清:想象function1
,function2
和function3
各自测试不同的模板化函数。每个函数都需要针对int
,byte
,char
,double
等进行测试。我希望避免显式设置多个(即num_functions * num_types)测试对于每个功能。相反,我希望有一个指向测试函数的方法(function1
,function2
等)并为每个模板类型运行它,从而整合
function1<int>();
function1<byte>();
function1<char>();
function1<double();
...
function2<int>();
function2<byte>();
function2<char>();
function2<double();
...
function3<int>();
function3<byte>();
function3<char>();
function3<double();
...
每个测试函数只需一次调用
testAcrossTypes(function1);
testAcrossTypes(function2);
testAcrossTypes(function3);
答案 0 :(得分:5)
你想用
完成什么void testAcrossTypes(SomeType f) {
f<int> ();
f<bool> ();
f<char> ();
f<double> ();
}
如果SomeType
可以是模板模板参数,则可以。但是,该标准不允许将函数模板用作模板模板参数。
来自C ++ 11标准:
14.3.3模板模板参数
1模板模板参数的 template-argument 应为类模板或别名模板的名称,表示为id-expression。
您最好的选择是使用仿函数而不是函数。例如:
template<typename T>
struct function1
{
void operator()() {
return;
}
};
template<typename T>
struct function2
{
void operator()() {
return;
}
};
template < template <typename> class F>
void testAcrossTypes() {
F<int>()();
F<bool>()();
F<char>()();
F<double>()();
}
int main()
{
testAcrossTypes<function1>();
testAcrossTypes<function2>();
}
答案 1 :(得分:3)
您可以通过类型擦除的仿函数来完成它,如下例所示:
#include<vector>
template<typename T>
void function1() { }
template<typename T>
void function2() { }
template<typename T>
void function3() { }
struct Test {
template<typename T>
static void proto() {
function1<T>();
function2<T>();
function3<T>();
}
void operator()() {
for(auto &f: vec) f();
}
template<typename... T>
static Test create() {
Test test;
int arr[] = { (test.vec.emplace_back(&proto<T>), 0)... };
(void)arr;
return test;
}
using func = void(*)(void);
std::vector<func> vec;
};
void testAcrossTypes(Test test) {
test();
}
int main() {
testAcrossTypes(Test::create<int, bool, char, double>());
}
在这两种情况下都很容易修改:
新功能需要添加到proto
静态成员方法,而且全部
添加新类型是在调用create
时使用它的问题,如上例所示
仿函数将负责创建要执行的N * M次呼叫 而且,您不需要在一堆结构中移动函数以便能够使用它们。