尝试使用
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
。我没有在标准中找到任何与此相关的内容。有没有办法将它与逗号运算符一起使用或与其他表达式(不带分号)一起使用?
不,没有。语言语法要求静态断言末尾有一个分号声明。
N4140 §7 [dcl.dcl]/1
static_assert-声明:
常量表达式 , 字符串文字static_assert (
;)
有没有办法将它与逗号运算符一起使用或与其他表达式(不带分号)一起使用?
正如其他答案中已经提到的,在处理
static_assert
时不能避免使用分号。int main() {
int c = ([]{ static_assert(true, "!"); }(), 4);
}
您可能想测试比
true
更复杂的东西。template<bool b>
void f() {
int c = ([](){ static_assert(b, "!"); }(), 4);
// ...
}
优化后,使用 lambda 的生成代码不会有太大差异(您可以使用这些最小示例在 godbolt 上轻松检查它)。
你可以把它包裹成一个块:
int c = ({ static_assert(true); }, 4);
一个选项是使用语句表达式(GCC 扩展,除 MSVC 之外的所有内容都支持):
int c = ( ({ static_assert(true); }), 4);
如果在启用
-Wcomma
警告的情况下进行编译,则需要将静态断言语句表达式强制转换为 void
以解决“可能误用逗号运算符”警告消息:
int c = ( (void)({ static_assert(true); }), 4);