所有模板实例的 C++ 单一函数指针
C++ Single function pointer for all template instances
是否有一种不使用宏而指向模板函数的所有实例的简洁方法?
我有几个模板化函数,我想测试各种类型:
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);
你想用
完成什么
void testAcrossTypes(SomeType f) {
f<int> ();
f<bool> ();
f<char> ();
f<double> ();
}
如果 SomeType
可以是模板模板参数,则 是可能的。但是,标准不允许函数模板作为模板模板参数。
来自 C++11 标准:
14.3.3 Template template arguments
1 A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as 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>();
}
您可以通过类型擦除仿函数来完成它,如下例中的仿函数:
#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 个调用。
此外,您无需将函数移动到一堆结构中即可使用它们。
是否有一种不使用宏而指向模板函数的所有实例的简洁方法?
我有几个模板化函数,我想测试各种类型:
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);
你想用
完成什么void testAcrossTypes(SomeType f) {
f<int> ();
f<bool> ();
f<char> ();
f<double> ();
}
如果 SomeType
可以是模板模板参数,则 是可能的。但是,标准不允许函数模板作为模板模板参数。
来自 C++11 标准:
14.3.3 Template template arguments
1 A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as 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>();
}
您可以通过类型擦除仿函数来完成它,如下例中的仿函数:
#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 个调用。
此外,您无需将函数移动到一堆结构中即可使用它们。