面试题答案
一键面试优化方案
- 显式实例化:在需要使用函数模板的模块中,对特定类型进行显式实例化。例如,若函数模板
template <typename T> void func(T arg)
在main.cpp
中主要用于int
和double
类型,可在main.cpp
中添加template void func<int>(int arg);
和template void func<double>(double arg);
。 - 将模板定义移至头文件:把函数模板的定义直接放在头文件中,这样在每个包含该头文件的源文件中,编译器能直接获取定义,无需在链接时再去寻找模板定义。但为避免多次定义问题,可使用
#pragma once
或#ifndef/#define/#endif
进行头文件保护。
原理
- 显式实例化:编译器只需为显式实例化的类型生成代码,而不是在每个使用该模板的地方都进行实例化。这减少了编译时模板实例化的次数,从而缩短编译时间。
- 模板定义移至头文件:编译器在编译包含头文件的源文件时,能直接根据模板定义生成实例化代码,避免了链接时因找不到模板定义而导致的额外编译开销。
潜在影响
- 显式实例化:
- 优点:有效减少编译时间,尤其在大型项目中。对于不常使用的模板类型,可避免不必要的实例化。
- 缺点:如果后续需要新增使用的模板类型,需要手动添加显式实例化声明,增加维护成本。同时,如果显式实例化的类型过多,可能会使目标文件增大。
- 模板定义移至头文件:
- 优点:代码结构清晰,所有模板相关代码集中在头文件,便于维护和理解。减少了链接错误的可能性。
- 缺点:头文件包含的内容增多,可能会导致包含该头文件的源文件编译时间稍有增加,因为编译器需要处理更多代码。同时,可能会使头文件的依赖性更复杂。