为什么在这个类定义中不需要空参数列表?

iFr*_*cht 6 c++ templates class visual-studio c++11

当仅使用标准类型参数实例化具有模板化类类型的变量时,语法如下所示:

template<typename Arg = int>
class Templ;

Templ<>& myTempl;
Run Code Online (Sandbox Code Playgroud)

省略空参数列表<>应该给出编译错误,因为需要模板参数列表.

但很显然,(至少在VS2013),下面的声明中没有需要的模板参数列表:

template<typename Arg> //" = int" left out
class Templ{
    Templ& myTempl; //no <> here
};
Run Code Online (Sandbox Code Playgroud)

但为什么这有效呢?根据IntelliSense,Templ<int>编译器选择了正确的type(),因此它按预期工作,但成员声明是否仍然需要空参数列表?

编辑:不,它没有按预期工作.我没有仔细检查.当悬停在线上时Templ<short>::myTempl,IntelliSense会显示其类型short.

Tem*_*Rex 10

类名称被注入类范围

9个班级[班级]

2在看到类名后立即将类名插入到作用域中.类名也插入到类本身的范围内; 这被称为注入类名.出于访问检查的目的,inject-class-name被视为公共成员名称.类说明符通常称为类定义.一个类被认为是在看到它的类说明符的右括号之后定义的,即使它的成员函数一般尚未定义.可选的attribute-specifier-seq属于该类; 之后,属性说明符-seq中的属性被认为是类的属性.

类似于类模板

14.6.1本地声明的名称[temp.local]

1与普通(非模板)类一样,类模板具有注入类名(第9节).injectclass-name可以用作模板名称或类型名称.当它与template-argument-list一起使用时,作为模板模板参数的模板参数,或作为友元类模板声明的详细说明类型说明符中的最终标识符,它引用类模板本身.否则,它等同于template-name,后跟括在其中的类模板的template-parameters <>.

这样你就可以使用Templ你的意思Templ<Arg>.

  • 所以OP声称它选择`Templ <int>`只能在使用`Arg = int`进行测试时才是正确的. (2认同)

Jon*_*ely 8

这称为注入类名.

在类模板中,没有任何模板参数列表的模板名称引用当前实例化,因此Templ意味着Templ<Arg>(而不是 Templ<>哪个Templ<int>,因此不一定相同).