我遇到了一些关于varidaic模板的奇怪事件,这是我以前从未见过的。 为了保持简单,我将给出一个我想要实现的简单示例,真正的代码需要更多参与。
所以我有一个看起来像的函数:
template <typename T, typename F, typename ... Args>
static T Func( std::string str, Args&& ... args )
{
... Do something
}
然后我从不同的位置多次调用此函数,其中传递的类型的大多数时间是不同的。但是当我调试它时,当我寻找Func的符号时,我得到相同的函数地址有许多不同的符号:
00000000`70ba4ae0 Func<unsigned long,unsigned long (__stdcall*)(wchar_t const *),wchar_t const *>
00000000`70ba4ae0 Func<void *,void * (__stdcall*)(unsigned int),unsigned int>
00000000`70ba4ae0 Func<int,int (__stdcall*)(void *),void *>
所以它们基本上都是相同的功能。当我试图打电话时:
call Func<void *,void * (__stdcall*)(unsigned int),unsigned int>
在调试器中,我看到:
call Func<int,int (__stdcall*)(void *),void *>
我可以看到每个模板函数实例都有一个生成的符号,但每个具有相同参数数量且参数相同的字节大小的实例只链接到一个函数。
虽然我可以理解为什么会发生这种情况,但有没有办法强制每个功能都是独立的?
答案 0 :(得分:0)
问题确实是COMDAT折叠。关闭OPT:ICF和OPT:REF标志就行了。虽然值得注意的是,使用带有标志的VS 2017进行编译比使用VS 2013编译相同的代码产生了更“明智”的结果。