仅当模板参数为true时,才可以在函数中创建变量吗?
template<bool _CalcExtra>
int foo()
{
int local;
int local2;
for(work)
{
... work using local
if(_CalcExtra)
... additional work using local and local2
}
if(_CalcExtra)
return local2;
return local;
}
我假设当这样调用函数时,大多数编译器只会删除local2
foo<false>();
但是有没有一种编程的方法来确保不会分配local2?
答案 0 :(得分:4)
没有(标准的)方法可以知道哪些变量将在堆栈上分配,什么将仅放置在寄存器中,什么将被丢弃。临时信息也可能会溢出到堆栈中。
在这里,删除这些分支是简单的优化。您可以使用if constexpr
来确保它是
您还可以查看生成的汇编代码,以查看是否分配了什么。
在极端情况下,您可能希望对参数的值进行手动专业化,并且仅在local2
专业化中使用false
。
请注意,在使用堆栈空间之外,堆栈上的分配是免费的...进入函数时,只是将堆栈指针移动了4个字节。
答案 1 :(得分:1)
通常,不能保证至少分配了 local
或local2
,至少在给定存储位置的意义上。编译器经常使用CPU寄存器来存储局部变量,而编译器仅在
未使用的变量通常会被完全删除,并且编译器不会产生与它们相对应的任何程序集。
唯一的例外是变量的构造函数有一些可能是可见的副作用(例如,如果在构造时打开文件或打印出某些内容)。
也就是说,您可以有条件地使用local2
语句来确保编译器即使在调试模式下也不会生成与if constexpr
相对应的任何程序集, 在C ++ 17中引入):
template<bool _CalcExtra>
int foo()
{
int local;
if constexpr(_CalcExtra) {
int local2;
for(...)
{
... work using local
... additional work using local and local2
}
return local2;
} else {
for(...)
{
... work using local
}
return local;
}
}