模板代码增加二进制文件的大小

时间:2011-11-23 20:52:49

标签: c++ templates g++

通常说具有大量模板的代码会导致输出大小增加,但这是真的吗?

#include <iostream>

#if 0
void foo( const int &v)
{
    std::cout<<v<<std::endl;
}
#else
template< typename T >
void foo( const T &v)
{
    std::cout<<v<<std::endl;
}
#endif

int main ()
{
    foo(50);
}

上面的例子产生了不同大小的输出(6.19k带有功能,6.16k带有模板功能)。为什么带模板的版本更小?

如果重要,我使用g ++ 4.6.1,下一个选项-O3 -Wextra -Wall -pedantic。我不确定其他编译器的输出是什么。

2 个答案:

答案 0 :(得分:6)

也许是因为示例中的foo具有外部链接,因此即使内联调用它也会被发送到您的可执行文件中。

对于模板,如果内联调用,则没有理由发出隐式实例化的函数模板特化。

尝试将foo设为inline功能或将其设为static。如果要发出函数模板特化,则需要显式实例化它

#else
template< typename T >
void foo( const T &v)
{
    std::cout<<v<<std::endl;
}
template void foo(const int&);
#endif

这样做,我的度量为非模板函数和函数模板版本提供了完全相同的大小。

答案 1 :(得分:1)

当我们说模板生成更大的代码时,我们实际上意味着它们与其他形式的动态或静态多态相比更大,例如虚函数,函数指针,选择,函数重载等......

例如,假设您有一个非常大的类模板,而某些代码中只有一个位置intfloat之间存在差异。好吧,一个天真的编译器将复制整个类和代码,它最终会占用两倍的大小(它不是真的发生这样的事情但是为了这个例子的目的让我们假设)。如果你刚刚重载了那个方法,那么只有那部分代码会被复制。

这也会产生令人讨厌的副作用,因为它必须评估两倍的代码量,因此编译时间会更长。

你必须记住的是,每次将新类型用于模板代码时,整个代码都会使用新类型重新生成,而其他方法可能只是在这里和那里切换指针。