为何A::B是依赖名称而A不是?C++模板技术问询
问题解释
先看你提供的代码:
#include <type_traits> template<typename... Ts> void boo() { struct A { struct B {}; }; static_assert(std::is_class_v<A>); static_assert(std::is_class_v<A::B>); // 编译失败;需要添加typename } int main() { boo<int>(); }
为什么A不是依赖名称,而A::B是?
A是函数模板boo体内直接定义的局部结构体,它的定义完全不依赖模板参数Ts——不管你实例化boo时传入什么类型,A的结构都是固定不变的。编译器在模板定义阶段就能明确判定A是一个类型,所以不需要额外关键字。而
A::B属于限定名(带作用域的名称),C++标准对模板中的限定名有特殊规则:即使限定名的前缀(这里是A)是非依赖的,编译器也不会默认它后面的名称是类型——除非这个限定名属于类模板自身的成员(比如类模板内部嵌套的类型)。这里的A是函数模板内的局部类,不属于这类例外情况,所以编译器在模板定义阶段无法确定A::B一定是类型(有可能被误解为静态成员变量之类的非类型名称),必须用typename关键字显式声明这是一个类型,才能通过编译。
内容的提问来源于stack exchange,提问作者Maksim S.
相关产品推荐
相关产品推荐

