为什么允许某些非常量表达式作为 constexpr 逗号运算符的操作数?
Why are some non-constant expressions allowed as operands of a 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] and [gcc] 都接受了代码,所以也许我遗漏了一些使代码有效的相关标准规则?
左值到右值的转换不适用于逗号运算符的第一个参数,除非它是可变的。因此,(void)a, 2
和(void)b, 3
是常量表达式。
见[expr.comma]/1
... the left expression is a discarded-value expression ...
和[expr]/12
... The lvalue-to-rvalue conversion is applied [to a discarded-value expression] if and only if the expression is a glvalue of volatile-qualified
type and it is one of the following: ...
考虑一个简单的例子:
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] and [gcc] 都接受了代码,所以也许我遗漏了一些使代码有效的相关标准规则?
左值到右值的转换不适用于逗号运算符的第一个参数,除非它是可变的。因此,(void)a, 2
和(void)b, 3
是常量表达式。
见[expr.comma]/1
... the left expression is a discarded-value expression ...
和[expr]/12
... The lvalue-to-rvalue conversion is applied [to a discarded-value expression] if and only if the expression is a glvalue of volatile-qualified type and it is one of the following: ...