2017-05-07 16 views
2

常量参数我明白为什么下面的代码不编译很困惑:完全向前恒定评价

template <typename T, typename... Ts> 
void TEST(T&& t, Ts&&... ts) { 
    if constexpr(sizeof...(ts) > 0) { 
    TEST(std::forward<Ts>(ts)...); 
    static_assert(t == 2 , "parameter must be 2"); 
    } 
} 

template <typename... Ts> 
void VARIADIC(Ts&&... ts) { 
    TEST(std::forward<Ts>(ts)...); 
} 

int main(int argc, char* argv[]) { 
    constexpr int a1 = 2; 
    constexpr int a2 = 2; 
    VARIADIC(a1, a2); 
} 

基本上,我试图做传递给参数一些编译时检查功能VARIADIC。但是,编译器抱怨如下:

error: non-constant condition for static assertion 
    static_assert(t == 2 , "parameter must be 2"); 
    ^~~~~~~~~~~~~ 
error: ‘t’ is not a constant expression 

这是很明显的给定参数a1a2是常数,必须有执行上的可变参数检查某些方面。

+0

我们可以失去所有大写的东西吗? –

+2

有什么困惑?当它们作为常量表达式的一部分引入时,实体仅被视为常量表达式。显然,在某种意义上,函数的参数不是*常量表达式。但是,函数结果*可以是一个常量表达式。 –

+0

错误在TEST函数的定义中,可以用非常量值调用。你碰巧用恒定值调用TEST并不重要。 –

回答

4

函数参数不按照5.20 [expr.const]第2.9段核心常量表达式:变量或引用是唯一的核心常量表达式,如果它们与常量表达式或他们的生活时初始化定义范围内开始不断的表达。函数论证显然不满足。

背景是constexpr函数可以用运行时值调用。为了确定变量是否是函数内的常量表达式,它是否实际上用常量表达式调用是无关紧要的。无论调用是否具有常量表达式,函数的计算时间都是这样的:尽管参数在函数中的行为不是常量表达式,但结果仍然可以是常量表达式。