面试题答案
一键面试1. 实例化过程中依赖类型的解析
当实例化 MyClass<int>
时,编译器会按照以下方式处理依赖于模板参数 T
的类型:
- 两阶段查找:模板的实例化涉及两阶段查找。第一阶段是在模板定义时,编译器会查找不依赖于模板参数的名称。例如,如果
MyClass
中有一个成员函数调用了一个全局函数,而该全局函数的名称不依赖于T
,则在模板定义处查找该函数。第二阶段是在模板实例化时,编译器会查找依赖于模板参数的名称。对于依赖于T
的类型,其相关的名称会在实例化时查找。 - 依赖类型的解析:对于依赖于
T
的类型,编译器会在实例化MyClass<int>
时,将T
替换为int
,然后在实例化点查找相关的类型和成员。例如,如果MyClass
中有一个成员函数使用了T::inner_type
,编译器会在实例化MyClass<int>
时,查找int::inner_type
。如果int
没有inner_type
成员,编译器会报错。
2. 查找规则
- 注入类名:模板类名本身在其定义范围内被注入,因此可以在模板定义中使用,无需限定。例如,在
MyClass
的成员函数中可以直接使用MyClass
来引用自身。 - 限定名查找:对于依赖于模板参数的限定名(如
T::member
),编译器会在实例化时查找T
类型的定义中是否有该成员。如果T
是一个类类型,编译器会查找T
的成员定义;如果T
是一个命名空间,编译器会查找该命名空间中的成员。 - 非限定名查找:对于非限定名(如在成员函数中直接使用的变量名),编译器首先在局部作用域查找,然后在包含该模板定义的作用域查找。如果该名称依赖于模板参数,编译器会在实例化时再次查找。
3. 潜在的错误情况
- 类型不存在:如果在实例化时,依赖于模板参数的类型不存在,编译器会报错。例如,如果
MyClass
的成员函数使用了T::nonexistent_type
,而T
类型(如int
)没有nonexistent_type
,编译器会提示类型未定义错误。 - 成员不存在:类似地,如果依赖于模板参数的类型中不存在所需的成员,编译器会报错。例如,
MyClass
的成员函数调用T::nonexistent_member()
,而T
类型没有该成员函数,编译器会提示成员函数未定义错误。 - 歧义性:如果在查找依赖于模板参数的名称时存在多个匹配项,编译器会报错。例如,如果
T
类型从多个基类继承了同名成员,编译器无法确定使用哪个成员,会提示歧义错误。