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

发布于 2024-12-17 14:48:43 字数 475 浏览 2 评论 0原文

人们常说带有大量模板的代码会导致输出大小增加,但事实真的如此吗?

#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。我不确定其他编译器的输出是什么。

It is often said that the code with lots of templates is going to cause the output to increase in size, but is it really true?

#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);
}

The example above produces outputs of different sizes (6.19k with the function, and 6.16k with a template function). Why is the version with a template smaller?

If it matters, I am using g++ 4.6.1, with next options -O3 -Wextra -Wall -pedantic. I am not sure what is the output of other compilers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夕嗳→ 2024-12-24 14:48:43

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

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

尝试将 foo 设为内联 函数或将其设为静态。如果您想发出函数模板专业化,您需要显式实例化它,

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

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

Perhaps because foo in your example has external linkage so that it is emitted into your executable even if the call is inlined.

For the template, if the call is inlined there is no reason to emit an implicitly instantiated function template specialization.

Try making foo an inline function or making it static. If you want to emit the function template specialization you need to explicitly instantiate it

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

Doing this, my measures give the exact same size for the non-template function and the function template version.

宛菡 2024-12-24 14:48:43

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

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

这还有一个令人讨厌的副作用,即使编译时间更长,因为它必须计算两倍的代码量。

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

When we say templates are generating bigger code, what we actually mean is they are bigger compared to other forms of dynamic or static polymorphism such as virtual functions, function pointers, selection, function overload, etc...

For instance, let's suppose you have a very big class template and only one place in some code is there a difference between int and float. Well, a naive compiler will duplicate the whole class and code and it will end up taking twice the size (it's not really happening like this but for the purpose of this example let's suppose). If you had just overloaded that one method, only that part of the code would have been duplicated.

This also have the nasty side effect of making the compile time longer since it has to evaluate twice the amount of code.

What you have to keep in mind is that every time a new type is used for a template code, the whole code gets regenerated with the new type, while other methods might simply switch pointers here and there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文