面试题答案
一键面试1. 编写代码
// 定义InnerTemplateClass
template<typename T>
class InnerTemplateClass {
public:
T data;
InnerTemplateClass(T value) : data(value) {}
};
// 定义TemplateClass
template<typename T>
class TemplateClass {
private:
InnerTemplateClass<T> innerInstance;
public:
TemplateClass(T value) : innerInstance(value) {}
};
2. 模板特化与实例化问题
- 模板特化:当针对特定类型需要不同实现时,可进行模板特化。例如,如果希望
InnerTemplateClass
针对int
类型有特殊处理,可以这样写:
template<>
class InnerTemplateClass<int> {
public:
int data;
InnerTemplateClass(int value) : data(value * 2) {}
};
- 实例化:模板在使用时才会实例化。编译器会根据模板参数生成具体的类或函数。例如,当
TemplateClass<int> obj(5);
时,编译器会实例化TemplateClass<int>
和InnerTemplateClass<int>
。为确保正确实例化,要保证模板定义在实例化之前可见。
3. 确保正确手动调用构造函数
通过在 TemplateClass
的构造函数初始化列表中调用 InnerTemplateClass
的构造函数,可确保正确调用。例如 TemplateClass(T value) : innerInstance(value) {}
,这会调用 InnerTemplateClass
的带参数构造函数。
4. 不同编译器差异分析及处理方法
- GCC:GCC 对模板支持较好,遵循标准。只要代码符合标准,一般无需特殊处理。例如上述代码可直接编译运行。
- Clang:Clang 同样对模板支持良好,与 GCC 类似,标准代码能正常编译。若遇到问题,通常是代码不规范导致,可检查语法及模板使用是否符合标准。
- MSVC:MSVC 在处理模板时可能存在一些与标准的细微差异。例如,对于模板成员函数的分离编译,MSVC 可能要求更严格。若出现链接错误,可将模板类的定义和实现放在同一个头文件中,避免分离编译问题。例如:
// TemplateClass.h
template<typename T>
class InnerTemplateClass {
public:
T data;
InnerTemplateClass(T value) : data(value) {}
};
template<typename T>
class TemplateClass {
private:
InnerTemplateClass<T> innerInstance;
public:
TemplateClass(T value) : innerInstance(value) {}
};
然后在需要使用的地方包含该头文件即可。这样可避免因分离编译导致的链接问题,保证在 MSVC 中正常编译。