C++ 模板歧义实例化
C++ template ambiguous instantiation
我正在尝试使用模板进行一些插值,但出现 "ambiguous template instantiation" 错误。这是代码
// 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);
}
};
基本上,我正在尝试实施梯形法则以使其静态展开。
但是,编译器似乎对使用 "termination case" 还是 "trapezoidal sum" 感到困惑。我做错了什么,有解决方法吗?我想强制它使用 "termination case" if 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;
}
您可以尝试通过添加额外的模板参数来消除歧义。
可能是
// .................................................VVVVVVVVVVV
template <int n, int k, InterRule rule, class Expr, bool = true>
struct Integration {
// ...
};
false
明确的地面案例
template <int n, InterRule rule, class Expr>
struct Integration<n, 0, rule, Expr, false> { // <--- false !
static double integrate(double a, double b){
return 0;
}
};
并在递归调用中添加正确的参数
return (b-a)/n * Expr::eval(a + (k-1)*(b-a)/n)
+ Integration<n, k - 1, rule, Expr, (k>1)>::integrate(a,b);
// ....................................^^^^^
下面是一个完整的编译示例
#include <cmath>
#include <iostream>
// interpolation rules
enum InterRule {trap, rect, trapSum};
// Rectangle rule
template <int n, int k, InterRule rule, class Expr, bool = true>
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, (k>1)>::integrate(a,b);
}
};
// termination case
template <int n, InterRule rule, class Expr>
struct Integration<n, 0, rule, Expr, false> {
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,(k>1)>::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,(k>1)>::integrate(a,b);
}
};
// 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;
}
我正在尝试使用模板进行一些插值,但出现 "ambiguous template instantiation" 错误。这是代码
// 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;
}
您可以尝试通过添加额外的模板参数来消除歧义。
可能是
// .................................................VVVVVVVVVVV
template <int n, int k, InterRule rule, class Expr, bool = true>
struct Integration {
// ...
};
false
template <int n, InterRule rule, class Expr>
struct Integration<n, 0, rule, Expr, false> { // <--- false !
static double integrate(double a, double b){
return 0;
}
};
并在递归调用中添加正确的参数
return (b-a)/n * Expr::eval(a + (k-1)*(b-a)/n)
+ Integration<n, k - 1, rule, Expr, (k>1)>::integrate(a,b);
// ....................................^^^^^
下面是一个完整的编译示例
#include <cmath>
#include <iostream>
// interpolation rules
enum InterRule {trap, rect, trapSum};
// Rectangle rule
template <int n, int k, InterRule rule, class Expr, bool = true>
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, (k>1)>::integrate(a,b);
}
};
// termination case
template <int n, InterRule rule, class Expr>
struct Integration<n, 0, rule, Expr, false> {
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,(k>1)>::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,(k>1)>::integrate(a,b);
}
};
// 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;
}