我真正想做的是比较以不同方式解决同一任务的不同算法的性能。这样的算法,在我的例子中称为apply_10_times
,有子算法,它们应该是可切换的,并且还接收模板参数。在我的示例中,它们被称为apply_x
和apply_y
,并将int SOMETHING
作为模板参数。
我认为解决方案是指定一个模板函数作为另一个模板功能的模板参数。类似这样的东西,其中template_function
当然是伪代码:
template<int SOMETHING>
inline void apply_x(int &a, int &b) {
// ...
}
template<int SOMETHING>
inline void apply_y(int &a, int &b) {
// ...
}
template<template_function APPLY_FUNCTION, int SOMETHING>
void apply_10_times(int &a, int &b) {
for (int i = 0; i < 10; i++) {
cout << SOMETHING; // SOMETHING gets used here directly as well
APPLY_FUNCTION<SOMETHING>(a, b);
}
}
int main() {
int a = 4;
int b = 7;
apply_10_times<apply_x, 17>(a, b);
apply_10_times<apply_y, 19>(a, b);
apply_10_times<apply_x, 3>(a, b);
apply_10_times<apply_y, 2>(a, b);
return 0;
}
我读到不可能将模板函数作为模板参数传递,所以我不能以这种方式传递APPLY_FUNCTION
。解决方案afaik是使用包装struct
,然后将其称为函子,并将函子作为模板参数传递。以下是我用这种方法得到的:
template<int SOMETHING>
struct apply_x_functor {
static inline void apply(int &a, int &b) {
// ...
}
};
template<int SOMETHING>
struct apply_y_functor {
static inline void apply(int &a, int &b) {
// ...
}
};
template<typename APPLY_FUNCTOR, int SOMETHING>
void apply_10_times(int &a, int &b) {
for (int i = 0; i < 10; i++) {
cout << SOMETHING; // SOMETHING gets used here directly as well
APPLY_FUNCTOR:: template apply<SOMETHING>(a, b);
}
}
这种方法显然有效。然而,APPLY_FUNCTOR:: template apply<SOMETHING>(a, b);
行在我看来相当难看。我更喜欢使用类似APPLY_FUNCTOR<SOMETHING>(a, b);
的东西,事实上,这似乎可以通过重载operator()
来实现,但我无法使其工作。有可能吗?如果有,怎么做?
由于不清楚为什么需要APPLY_FUNCTION
和SOMETHING
作为单独的模板参数,或者为什么需要它们作为模板参数,我将说明显而易见的解决方案,它可能不适用于您的实际情况,但适用于问题中的代码。
#include <iostream>
template<int SOMETHING>
inline void apply_x(int a, int b) {
std::cout << a << " " << b;
}
template<int SOMETHING>
inline void apply_y(int a, int b) {
std::cout << a << " " << b;
}
template<typename F>
void apply_10_times(int a, int b,F f) {
for (int i = 0; i < 10; i++) {
f(a, b);
}
}
int main() {
int a = 4;
int b = 7;
apply_10_times(a, b,apply_x<17>);
apply_10_times(a, b,apply_y<24>);
}
如果你想保留要调用的函数作为模板参数,你可以使用函数指针作为非类型模板参数:
template<void(*F)(int,int)>
void apply_10_times(int a, int b) {
for (int i = 0; i < 10; i++) {
F(a, b);
}
}
int main() {
int a = 4;
int b = 7;
apply_10_times<apply_x<17>>(a, b);
apply_10_times<apply_y<24>>(a, b);
}
无论如何,我认为没有理由将APPLY_FUNCTION
和SOMETHING
作为单独的模板参数。唯一的好处是更复杂的语法,这正是你想要避免的。如果您确实需要从apply_x
或apply_y
的实例化中推断SOMETHING
,那么在不单独传递模板及其参数的情况下,这也是可行的,不过您需要使用类模板而不是函数模板。
PS:
啊,现在我明白你的意思了。是的,apply_10_times((也直接使用SOMETHING。对不起,我把问题中的代码简化得太多了。
如上所述。这并不意味着你需要分别通过它们。您可以通过部分模板专门化从apply_x<SOMETHING>
推导出SOMETHING
。然而,这需要使用类模板而不是函数模板:
#include <iostream>
template <int SOMETHING>
struct foo {};
template <int X>
struct bar {};
template <typename T>
struct SOMETHING;
template <template <int> class T,int V>
struct SOMETHING<T<V>> { static constexpr int value = V; };
int main() {
std::cout << SOMETHING< foo<42>>::value;
std::cout << SOMETHING< bar<42>>::value;
}
我真正想做的是比较不同以不同方式解决同一任务的算法。
您应该提供更多详细信息。
你的第一步应该是熟悉谷歌基准测试。有一个网站在线提供。该工具为您的场景提供了适当的模式。
在下一步中,您必须意识到在CCD_ 20和CCD_;就好像规则";这允许优化器做一些出色的事情,但却使创建良好的性能测试变得极其困难。这是一个简单的写测试,不测量实际的生产代码。
下面是cppcon演讲,展示了在对C++代码进行良好性能测试时隐藏了多少陷阱。所以要非常小心。