奇怪的海湾合作委员会“预期初级表达......”错误

时间:2010-06-16 17:34:04

标签: c++ templates gcc

  

可能重复:
  Templates: template function not playing well with class’s template member function

template <typename T>
struct A
{
    template <int I>
    void f();
};

template <typename T>
void F(A<T> &a)
{
    a.f<0>(); // expected primary-expression before ‘)’ token
}

int main()
{
    A<int> a;

    a.f<0>(); // This one is ok.
}

它的全部意义?

3 个答案:

答案 0 :(得分:16)

当使用依赖名称来引用嵌套模板时,必须在嵌套名称前加上关键字template,以帮助编译器理解您所指的是嵌套模板并正确解析代码

template <typename T>
void F(A<T> &a)
{
    a.template f<0>();
}

main内,名称a不依赖,这就是您不需要额外的template关键字的原因。内部F名称a是依赖的,这就是需要关键字的原因。

当通过依赖名称引用嵌套类型名称时,这类似于额外的typename关键字。只是语法略有不同。

答案 1 :(得分:1)

在前者中,编译器认为你的意思是......

a.f < 0 ...gibberish....

安德烈的回答解决了这个问题。

答案 2 :(得分:0)

请注意,代码段,对 添加的关键字和添加有效,在每种情况下产生不同的结果,甚至对于采用类型参数而不是整数的模板。

#include <iostream>

struct A { 
  template<typename T> 
  static A f(T) { 
    return A(); 
  } 

  template<typename T> operator T() { return T(); }
}; 

template<typename U> 
int g() { 
  U u;
  typedef A (*funcPtrType)(int());
  return !(funcPtrType)u.f < int() > (0); 
}

int main() {
  std::cout << g<A>() << std::endl;
}

在未添加0关键字的情况下运行时输出template。如果您在f < int() >之前添加关键字,则会输出1


<强>解释

没有关键字的版本解析为

funcPtrType temp1 = (funcPtrType)u.f; // taking func address
bool temp2 = !temp1;                  // temp2 == false
bool temp3 = temp2 < int();           // temp3 == false
bool temp4 = temp3 > (0);             // temp4 == false
return temp4;

带有关键字的版本解析为

A temp1 = u.template f < int() > (0);     // function call
funcPtrType temp2 = (funcPtrType) temp1;  // temp2 == 0
bool temp3 = !temp2;                      // temp3 == true
return temp3;

请注意temp2是一个空指针(由return T()生成)。整个不同的解析,都是有效的!这确实需要一种消除歧义的方法 - 即在适当时插入template关键字。