类模板和函数模板被实例化,但别名模板被简单地替换。并去掉会员名type
,您将失去调用从属名称查找规则的机会。
[N3285] 14.5.7p2:
When a 模板 ID指别名模板的特化,相当于将其替换为关联类型模板参数为了模板参数 in the type-id别名模板的。
所以在第一种情况下,你有:
的定义struct derived
需要隐式实例化base<derived>
。在这个实例化过程中,我们发现base<derived>
有一个成员函数模板:
template <typename Delayer=void>
typename derived_value_type<derived, Delayer>::type foo();
返回类型是相关的,所以type
尚未查找,并且没有专门化derived_value_type
被实例化。实例化完成,并且base<derived>
and derived
现在都是完整的类型。
In main
, 表达方式d.foo()
需要隐式实例化base<derived>::foo<void>()
。现在的名字typename derived_value_type<derived, void>::type
被查找,实例化derived_value_type<derived, void>
一路上。发现返回类型是int
.
在第二种情况下,derived_value_type
不是依赖名称,因此绑定到模板定义中的别名模板声明base<D>
。编译器可以在模板定义时或在类的每次实例化期间进行别名替换,但无论哪种方式,您都会获得相当于以下内容的类模板:
template <typename Derived>
struct base
{
template <typename Delayer = void>
typename Derived::value_type
foo(){ return {}; }
};
的定义struct derived
需要隐式实例化base<derived>
。在这个实例化过程中,我们发现base<derived>
有一个成员函数模板:
template <typename Delayer=void>
typename derived::value_type foo();
But derived::value_type
不依赖,并且derived
是不完整类型,因此代码格式错误。