当尝试使用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
。我没有设法在标准中找到任何相关的内容。有没有办法使用它与逗号运算符或使用它与其他表达式(没有分号)?
答案 0 :(得分:5)
不,没有。语法语法在静态断言声明的末尾需要一个分号。
N4140§7[dcl.dcl] / 1
static_assert声明:
static_assert (
常量表达式, string-literal)
;
答案 1 :(得分:3)
有没有办法将它与逗号运算符一起使用或与其他表达式一起使用(不带分号)?
正如其他答案中已经提到的,在处理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上轻松检查它。)
答案 2 :(得分:1)
你可以将它包装在一个块中:
int c = ({ static_assert(true); }, 4);