【发布时间】:2020-02-23 14:51:27
【问题描述】:
我正在尝试使用模板进行一些插值,但我收到“模版模版不明确”错误。这是代码
// interpolation rules
enum InterRule {trap, rect, trapSum};
// Rectangle rule
template <int n, int k, InterRule rule, class Expr> struct Integration {
static double integrate(double a, double b){
return (b-a)/n * Expr::eval(a + (k-1)*(b-a)/n) + Integration<n, k - 1, rule, Expr>::integrate(a,b);
}
};
// termination case
template <int n, InterRule rule, class Expr> struct Integration<n,0,rule,Expr> {
static double integrate(double a, double b){
return 0;
}
};
// Trapezoidal rule
template <int n, int k, class Expr> struct Integration<n, k, trap, Expr> {
static double integrate(double a, double b){
return (b-a)/n * (Expr::eval(a)/2 + Integration<n,k-1,trapSum,Expr>::integrate(a,b) + Expr::eval(b)/2);
}
};
// Trapezoidal sum
template <int n, int k, class Expr> struct Integration<n, k, trapSum, Expr> {
static double integrate(double a, double b){
return Expr::eval(a + k*(b-a)/n) + Integration<n,k-1,trapSum,Expr>::integrate(a,b);
}
};
基本上,我正在尝试实现梯形规则,使其静态展开。
但是,编译器似乎对使用“终止情况”还是“梯形和”感到困惑。我做错了什么,有解决方法吗?如果k==0 无论InterRule 规则的类型如何,我都想强制它使用“终止案例”。
编辑 使其运行的附加代码:
// the types of expressions (+,-,*, etc.)
enum ExprType { mul, divide, add, sub, constant};
// constant
template <ExprType eType, class Left, class Right, int coeff, int power> struct Expr {
static double eval(double x){
return coeff * std::pow(x, power);
}
};
int main()
{
double a = 1;
double b = 2;
// Expr defines the function f(x) = x
Integration<50, 50, trap, Expr<constant,int,int,1,1>> inte2;
std::cout << inte2.integrate(a,b) << std::endl;
return 0;
}
【问题讨论】:
-
可以加个使用例子吗?
-
请提供minimal reproducible example。您显示的代码不会实例化任何模板。还有“使其静态展开”:我不确定您的意思。如果您在这里使用模板的唯一原因是您认为它会运行得更快,那么您很可能错了。无论如何,编译器很可能会内联所有内容,然后常量参数是模板参数还是常规函数参数都没有关系。此外,过多地展开循环可能会使性能变差。让编译器决定如何处理。
-
最后,从 C++17 开始,这样的事情可以在没有使用 fold 表达式的所有模板的情况下更快更清晰地完成。
-
@walnut 我添加了代码来完成示例。我出于好奇而使用模板并学习它们,因此效率并不重要。
-
@Timo 我添加了它。
标签: c++ templates variadic-templates template-meta-programming template-specialization