在面试时我曾经被问到一个技巧问题:模板化的课程是否比另一个相同但没有模板化的课程占用更多的内存?我的回答是否定的,但他问这个问题意味着可能存在这样的情况.或者,他真的想和我说话.模板化的类会占用更多内存的情况会怎样?
Dav*_*eas 15
首先要明确问题的含义是什么.如果问题是该类型的对象是否会更大(即sizeof(T<int>) > sizeof(T_int))那么答案是否定的.如果问题是关于应用程序本身的二进制占用空间,包括函数的代码,那么答案是在模板的情况下程序的整体大小实际上可能更小,因为只编译了使用的成员函数(除非明确实例化).虽然在一天结束时,链接器也可能会丢弃非模板版本中未使用的成员.
有一个常用术语:代码膨胀,用于指代模板生成的代码爆炸.该术语指的是模板的每个不同实例化将生成其自己的函数的事实,并且这可以导致在可执行文件中存在比允许参数的转换的更小的非模板函数集更多的函数.
考虑矢量模板的可能接口:
template <typename T>
class Vector {
template <typename U> void push_back(U u);
//....
Run Code Online (Sandbox Code Playgroud)
对于每个push_back使用不同参数类型的调用,将生成一个新函数,因此将有一个函数Vector<int>::push_back('a')和另一个函数Vector<int>::push_back(1).将其与std::vector成员函数不是模板的接口进行比较,调用者进行类型转换.
虽然这可能是更大的可执行文件的来源,但我不认为这是要求的.特别是,对于模板化类型和为特定实例化类型手工制作的等效非模板类型,生成的代码应该是等效的(忽略模板的受损名称往往更大的事实:))
就记忆而言,答案是否定的.我的意思是,它不一定要占用更多的内存,尽管一些邪恶的家伙可能会编写一个类模板,只是为了证明他的观点,即类模板版本需要更多的内存.
但是,类模板的源代码可能比类型参数的特定值的非模板clas版本更大(或者更小).
template<typename T>
struct point_t
{
T x, y, z;
};
struct point_int
{
int x, y, z;
};
std::cout << (sizeof(point_int) == sizeof(point_t<int>)) << std::end;
Run Code Online (Sandbox Code Playgroud)
它将打印true(或1).
请注意,内存布局point_int和point_t<int>将是相同的.所以你甚至可以这样投:
point_t<int> pt {10, 20, 30};
point_int pi = *reinterpret_cast<point_int*>(&pt);
std::cout << "{" << pi.x <<"," << pi.y <<"," << pi.z << "}" << std::endl;
Run Code Online (Sandbox Code Playgroud)
它会打印出来{10, 20, 30}.
希望有所帮助.