从另一个模板化函数中调用模板化函数时接收'expected primary-expression'

时间:2013-12-27 17:17:28

标签: c++ templates c++11

这是一个最小化的简化,它重现了我在更大的代码库中看到的错误。简而言之,我想使用不同的数字类型(intdouble等对线段进行建模。)

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

1 个答案:

答案 0 :(得分:4)

如果依赖名称前面带有关键字template,则该名称仅被视为模板。你需要打电话给你这样的功能:

a.template cast<double>()

基本思想是编译器应该能够在解析模板时决定它遇到的实体类型。由于模板参数在读取模板定义时是未知的,因此需要一些帮助才能知道它看到了什么。当使用嵌套名称时,它类似于所需的typename