带 static_assert() 的逗号运算符
Comma operator with static_assert()
尝试以 static_assert
作为参数计算逗号运算符时编译失败
void fvoid() {}
int main() {
int a = (1, 2); // a=2
int b = (fvoid(), 3); // b=3
int d = ( , 5);
// ^
// error: expected primary-expression before ',' token. OK
int c = (static_assert(true), 4);
// ^~~~~~~~~~~~~
// error: expected primary-expression before 'static_assert'. Why?
}
看起来 static_assert()
在编译后甚至没有解析为 void
。我没有设法在标准中找到与此相关的任何内容。有没有办法将它与逗号运算符一起使用或与其他表达式(不带分号)一起使用?
不,没有。语言语法要求static assert declaration.
末尾有分号
N4140 §7 [dcl.dcl]/1
static_assert-declaration:
static_assert (
constant-expression , string-literal )
;
Is there a way to use it with comma operator or use it in line with other expression (without semicolon)?
正如其他答案中已经提到的,在处理 static_assert
.
时,您无法避免使用分号
无论如何,您可以按如下方式将其包装在 lambda 中,并仍然以某种方式与逗号运算符一起使用它:
int main() {
int c = ([]{ static_assert(true, "!"); }(), 4);
}
您可能想测试比 true
更详细的内容。
在这种情况下,您必须解决当前 lambda 定义的(让我说)限制(布尔值既不能捕获也不能作为参数传递)。
具有非类型模板参数的函数模板可以完成这项工作。例如:
template<bool b>
void f() {
int c = ([](){ static_assert(b, "!"); }(), 4);
// ...
}
优化后,使用 lambda 的结果代码差别不大(您可以使用这些最小示例在 godbolt 上轻松检查)。
您可以将其包裹在一个块中:
int c = ({ static_assert(true); }, 4);
尝试以 static_assert
作为参数计算逗号运算符时编译失败
void fvoid() {}
int main() {
int a = (1, 2); // a=2
int b = (fvoid(), 3); // b=3
int d = ( , 5);
// ^
// error: expected primary-expression before ',' token. OK
int c = (static_assert(true), 4);
// ^~~~~~~~~~~~~
// error: expected primary-expression before 'static_assert'. Why?
}
看起来 static_assert()
在编译后甚至没有解析为 void
。我没有设法在标准中找到与此相关的任何内容。有没有办法将它与逗号运算符一起使用或与其他表达式(不带分号)一起使用?
不,没有。语言语法要求static assert declaration.
末尾有分号N4140 §7 [dcl.dcl]/1
static_assert-declaration:
static_assert (
constant-expression , string-literal)
;
Is there a way to use it with comma operator or use it in line with other expression (without semicolon)?
正如其他答案中已经提到的,在处理 static_assert
.
时,您无法避免使用分号
无论如何,您可以按如下方式将其包装在 lambda 中,并仍然以某种方式与逗号运算符一起使用它:
int main() {
int c = ([]{ static_assert(true, "!"); }(), 4);
}
您可能想测试比 true
更详细的内容。
在这种情况下,您必须解决当前 lambda 定义的(让我说)限制(布尔值既不能捕获也不能作为参数传递)。
具有非类型模板参数的函数模板可以完成这项工作。例如:
template<bool b>
void f() {
int c = ([](){ static_assert(b, "!"); }(), 4);
// ...
}
优化后,使用 lambda 的结果代码差别不大(您可以使用这些最小示例在 godbolt 上轻松检查)。
您可以将其包裹在一个块中:
int c = ({ static_assert(true); }, 4);