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

W.F*_*.F. 10 c++ comma-operator language-lawyer constexpr c++11

考虑一个简单的例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*ian 10

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

见[expr.comma]/1

...左表达式是丢弃值表达式...

和[expr]/12

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