这是一个最小化的简化,它重现了我在更大的代码库中看到的错误。简而言之,我想使用不同的数字类型(int
,double
等对线段进行建模。)
template<typename T>
class Vector2
{
public:
Vector2(T x, T y)
: x(x), y(y)
{}
template<typename U>
Vector2<U> cast() const { return Vector2<U>((U)x, (U)y); }
T x;
T y;
};
template<typename T>
class Line2
{
public:
Line2(Vector2<T> a, Vector2<T> b)
: a(a), b(b)
{}
double gradient() const
{
Vector2<double> ad(a.cast<double>()); // ERROR HERE
Vector2<double> bd(b.cast<double>()); // ERROR HERE
return (bd.y - ad.y) / (bd.x - ad.x);
}
Vector2<T> a;
Vector2<T> b;
};
线段上的某些操作需要将坐标转换为double
,例如渐变计算。因此,矢量类型支持转换。
cast
的调用在这样调用时工作正常:
Line2<int> i(Vector2<int>(0,0), Vector2<int>(1,3));
Line2<double> d(Vector2<double>(0,0), Vector2<double>(0.5,1.23));
以下代码通过cast
成员函数间接调用gradient
:
Line2<int> i(Vector2<int>(0,0), Vector2<int>(1,3));
Line2<double> d(Vector2<double>(0,0), Vector2<double>(0.5,1.23));
std::cout << "Line2<int>.gradient = " << i.gradient() << std::endl;
std::cout << "Line2<double>.gradient = " << d.gradient() << std::endl;
这会产生以下编译错误:
test.cpp: In member function ‘double Line2<T>::gradient() const’:
test.cpp:28:31: error: expected primary-expression before ‘double’
Vector2<double> ad(a.cast<double>());
^
test.cpp:28:31: error: expected ‘)’ before ‘double’
test.cpp:29:31: error: expected primary-expression before ‘double’
Vector2<double> bd(b.cast<double>());
^
为什么会出现此错误?如何绕过它?
我知道这可以通过在梯度算术表达式中进行处理来解决,但我的实际代码更复杂并且使用了Eigen3矩阵类。大多数情况下,我只是想了解这个错误。
完整代码和编译错误:http://ideone.com/nwAdTN
答案 0 :(得分:4)
如果依赖名称前面带有关键字template
,则该名称仅被视为模板。你需要打电话给你这样的功能:
a.template cast<double>()
基本思想是编译器应该能够在解析模板时决定它遇到的实体类型。由于模板参数在读取模板定义时是未知的,因此需要一些帮助才能知道它看到了什么。当使用嵌套名称时,它类似于所需的typename
。