为什么允许某些非常数表达式作为constexpr逗号运算符的操作数?

时间:2018-12-03 18:28:32

标签: c++ c++11 language-lawyer constexpr comma-operator

考虑一个简单的例子:

int foo() {
    return 3;
}

template <int>
struct Bar {};

int a;

int main() {
    int b;
    //Bar<((void)foo(), 1)> bar1;  //case 1. compilation error as expected
    Bar<((void)a, 2)> bar2;        //case 2. no error (long shot but `a' has a linkage so maybe expected)
    Bar<((void)b, 3)> bar3;        //case 3. no error ? (`b' does not have linkage) 
    (void)bar2;
    (void)bar3;
}

我会说这是一个错误,但是最新的[clang][gcc]都接受代码,所以也许我缺少使代码有效的一些相关标准规则?

1 个答案:

答案 0 :(得分:10)

左值到右值的转换不会应用于逗号运算符的第一个参数,除非它是易变的。因此,(void)a, 2(void)b, 3是常量表达式。

请参阅[expr.comma] / 1

  

...左边的表达式是一个废弃值表达式...

和[expr] / 12

  

...当且仅当表达式是volatile限定的glvalue时,才将[左值到右值]转换应用于[丢弃值表达式]   类型,它是以下之一:...