error: use 'template' keyword to treat 'xx' as a dependent template name

调用模板类限定的模板函数时,即形如:A<typename_a>::member_function<typename_b>()这样的调用时;

必须使用关键字template进行说明,即改为:A<typename_a>:: template member_function<typename_b>();

否则可能报错:

error: use 'template' keyword to treat 'xx' as a dependent template name

或者

error: expected primary-expression before‘double’

上面这两个报错是对同一问题的报错,不同的编译器的提示内容可能不同。其错误代码可抽象为如下:

#include <iostream>
#include <vector>
using namespace std;

template <int dim>
struct EulerEquations                                //注意:这里EulerEquations是个模板类
{
   template <typename number, typename InputVector>  //相当于是个位于EulerEquations命名空间下的模板函数
   static
   number
   compute_pressure (const InputVector &W)     
   {
   return *(W.begin());
   }
};

void
compute_drag()
{ 
   std::vector<double> W(4);
   W[0]=78;
   W[1]=2.;
   W[2]=1.5423;
   W[3]=0.543;
   double pressure = EulerEquations<dim>::compute_pressure<double>(W);  //错误所在行
   cout<<pressure;
}

int main()
{
   compute_drag<2>();
   return 0;
}
在上面的错误所在行,提示error: use 'template' keyword to treat 'compute_pressure' as a dependent template name
   double pressure = EulerEquations<dim>::compute_pressure<double>(W);
                                          ^

                                          template 

这句话的意思是compute_pressure模板函数在这里必须用关键字"template"进行修饰。也就是改为:

double pressure = EulerEquations<dim>::template compute_pressure<double>(W);

这样才能告诉编译器,在限定符::后面的这个函数是个模板函数,而非普通的静态函数。如果不加template关键字,则编译到这里的时候,会认为double前的<符号是小于符号,这也就是为什么有的编译器在遇到这种情况的时候会提示:error: expected primary-expression before ‘double’ double pressure = EulerEquation<dim>::compute_pressure<double>(W);

                                                           ^
error: expected ‘,’ or ‘;’ before ‘double’

在stackover flow上有类似的错误,比如https://stackoverflow.com/questions/3786360/confusing-template-error

其解释为:

ISO C++03 14.2/4:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

即:当一个成员模板实例的名字(B)出现在一个后缀(下标)表达式的 .或者->之后,或者在一个qualified-id(即A::B)里的嵌套名称说明符(即A::)之后,且该后缀表达式或者qualified-id显式地依赖于某个模板参数,那么成员模板的名称必须加以关键字template。否则,该名称被假定为非模板名。

注:Given:

struct  A {
    struct B {
        void F();
    };
};
  • A is an unqualified-id.
  • ::A is a qualified-id but has no nested-name-specifier.
  • A::B is a qualified-id and A:: is a nested-name-specifier.
  • ::A::B is a qualified-id and A:: is a nested-name-specifier.
  • A::B::F is a qualified-id and both B:: and A::B:: are nested-name-specifiers.
  • ::A::B::F is a qualified-id and both B:: and A::B:: are nested-name-specifiers.

在上面的例子中:

double pressure = EulerEquations<dim>::compute_pressure<double>(W);

成员模板实例compute_pressure<double>()出现在了嵌套名称说明符(EulerEquations<dim>::)之后,且EulerEquations本身是依赖于某个模板参数的。所以必须在compute_pressure前加template,告诉编译器后面这个函数名是模板函数。

当然,如果EulerEquations不是模板类,即去掉它的template<dim>这一行,则在调用compute_pressure<double>()时不用加template。

猜你喜欢

转载自blog.csdn.net/qq_41230365/article/details/79769812