【问题标题】:Strange GCC 'expected primary expression...' error [duplicate]奇怪的 GCC '预期的主要表达式......'错误 [重复]
【发布时间】:2010-06-16 17:34:03
【问题描述】:

可能重复:
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.
}

这是怎么一回事?

【问题讨论】:

    标签: c++ templates gcc


    【解决方案1】:

    从属名称用于引用嵌套模板时,嵌套名称必须在前面加上关键字template,以帮助编译器理解您指的是嵌套模板并且正确解析代码

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      Andrey 的回答解决了这个问题。

      【讨论】:

        【解决方案3】:

        请注意,代码 sn-p 对 添加的关键字和 添加的关键字都有效,在每种情况下都会产生不同的结果,即使对于采用类型参数而不是整数的模板也是如此。

        #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;
        }
        

        在没有添加 template 关键字的情况下运行时输出 0。如果在f &lt; int() &gt; 之前添加关键字,则会输出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 关键字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-26
          • 1970-01-01
          • 1970-01-01
          • 2023-04-11
          相关资源
          最近更新 更多