C ++仅在模板参数为true时创建变量

时间:2019-06-07 21:34:02

标签: c++ templates

仅当模板参数为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?

2 个答案:

答案 0 :(得分:4)

没有(标准的)方法可以知道哪些变量将在堆栈上分配,什么将仅放置在寄存器中,什么将被丢弃。临时信息也可能会溢出到堆栈中。

在这里,删除这些分支是简单的优化。您可以使用if constexpr来确保它是

您还可以查看生成的汇编代码,以查看是否分配了什么。

在极端情况下,您可能希望对参数的值进行手动专业化,并且仅在local2专业化中使用false

请注意,在使用堆栈空间之外,堆栈上的分配是免费的...进入函数时,只是将堆栈指针移动了4个字节。

答案 1 :(得分:1)

通常,不能保证至少分配了 locallocal2,至少在给定存储位置的意义上。编译器经常使用CPU寄存器来存储局部变量,而编译器仅在

时才将变量分配给regsiter。
  • 为他们分配了一个值
  • 代码以某种方式使用它们

未使用的变量通常会被完全删除,并且编译器不会产生与它们相对应的任何程序集。

唯一的例外是变量的构造函数有一些可能是可见的副作用(例如,如果在构造时打开文件或打印出某些内容)。

也就是说,您可以有条件地使用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; 
    }
}