在模板函数中包含不变假设
Including an invariant assumption in a template function
考虑一个典型的有限差分应用:
// assuming T_size > 2
void process_T(double *T0, double *T, const int &T_size, bool periodic) {
for (int i = 0; i < T_size; ++i) {
double sum = 0;
double base = T0[i];
if (i > 0) sum += (T0[i-1]-base);
if (i < 0) sum += (T0[i+1]-base);
if (periodic) {
if (i == 0) sum += (T0[T_size-1]-base);
if (i == T_size-1) sum += (T0[0]-base);
} else {
if (i == 1 || i == T_size-1) sum += 0.5*(T0[i-1]-base);
if (i == 0 || i == T_size-2) sum += 0.5*(T0[i+1]-base);
}
T[i] = T0[i] + sum * 0.08; // where 0.08 is some magic number
}
}
对periodic
的检查是循环不变的,但由于仅在运行时知道,因此每次都会产生条件检查开销。我可以创建一个专门的函数来假设其中一种情况,但是维护公共基础会很麻烦,尤其是在三维问题的情况下,它会增长到 8 个函数(周期性:无、x、y、z、xy、xz、xyz)来考虑所有组合。
是否有可能通过元编程解决这个问题?
P/S:分支预测器可以相应地优化吗?
模板可能具有非类型参数:
template <bool periodic>
void process_T(double *T0, double *T, const int &T_size)
当然,这意味着在调用站点编写这样的东西的成本:
bool periodicFunction = {whatever};
if (periodicFunction)
process_T<true>(...);
else
process_T<false>(...);
是的,你可以有
enum Periodicity
{
PERIODICITY_NONE,
PERIODICITY_X,
PERIODICITY_Y
// etc
};
然后
template <Periodicity P>
void process_T(double* T0, double* T, const int& T_size)
{
if (P == PERIODICITY_NONE) // ... do something
if (P == PERIODICITY_X) // ... do something else
// Common code
}
任何像样的优化编译器都能够在编译时执行检查,并消除任何死代码(g++ 似乎即使在 -O0
时也能做到这一点)。
相关文章:
- g++ 说函数不存在,即使包含正确的标头
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 结构包含在两个头文件中,这两个文件我都不拥有
- 为什么 Same<T, U> 不包含 Same<U, T>?
- MAKE:找不到包含的用户定义的头文件?
- C++ 写入路径名中包含不需要的空字符的文件
- 无法打开包含文件'Graphics.hpp'没有这样的文件或目录,Visual Studio的其他包含不起作用
- 标头包含不是 .c 程序所必需的,而是.cpp程序需要的
- 无法转换 .CATPart 文件.错误:输入文件路径似乎包含不支持的字符
- C++ - 在类中包含不是类对象属性的变量是否是一种不好的做法
- 函数指针数组,其中包含不同类的类函数
- 表达式包含不匹配的括号
- C++第三方库包含不存在的头文件
- 在模板函数中包含不变假设
- 打开包含不存在文件的文件流后不会引发异常
- 创建可以包含不同类的变量
- c++主函数中包含不同类的相同函数
- C++包含不起作用
- C/ c++ -条件头文件包含不工作