为何第二次调用meow()可编译?F::E无嵌套E的模板推导疑问
为什么传入
F::E对象调用meow能成功编译? 先看这段代码的核心疑问:第二次调用meow(f.e)时,传入的是F::E类型的对象,但F::E本身并没有定义嵌套的E类型,为什么模板的第二个参数还能被正确推导?
关键原因:注入类名(Injected Class Name)机制
C++里有个容易被忽略的规则:每个类的名字会被自动注入到自身的作用域中,相当于这个类自己的作用域里有一个同名的类型成员。
对应到代码里:
struct F::E定义完成后,在F::E的内部作用域里,E就是F::E这个类型的别名(也就是注入类名)。- 当调用
meow(f.e)时,模板参数T被推导为F::E。此时模板的第二个参数默认值是typename T::E::is_it_safe,这里的T::E就是F::E自己(因为注入类名的存在),所以T::E::is_it_safe等价于F::E::is_it_safe,也就是bool。
这样第二个模板参数就被成功推导为bool,所以整个调用meow<F::E, bool>是合法的,编译器自然能通过编译。
直观验证
把模板参数的推导过程展开来看:
- 调用
meow(f):T=F,T::E是F里定义的嵌套类F::E,所以T::E::is_it_safe是bool,符合要求。 - 调用
meow(f.e):T=F::E,T::E是注入的类名(即F::E自身),所以T::E::is_it_safe还是F::E::is_it_safe即bool,完全合法。
内容的提问来源于stack exchange,提问作者Bulletmagnet
相关产品推荐
相关产品推荐

