带有static_assert()的逗号运算符

tei*_*vaz 5 c++ runtime 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?
}
Run Code Online (Sandbox Code Playgroud)

在编译之后,它看起来static_assert()甚至无法解决void.我没有在标准中找到任何关于此的内容.有没有办法使用它与逗号运算符或使用它与其他表达式(没有分号)?

krz*_*zaq 6

不,那里没有.语法语法在静态断言声明的末尾需要一个分号.

N4140§7[dcl.dcl]/1

static_assert-declaration:

static_assert ( 常数表达式,字串文本 ) ;


sky*_*ack 5

有没有办法将它与逗号运算符一起使用或与其他表达式(不带分号)一起使用?

正如其他答案中已经提到的,在处理static_assert.
无论如何,您可以将其包装在 lambda 中,如下所示,并且仍然以某种方式与逗号运算符一起使用它:

int main() {
    int c = ([]{ static_assert(true, "!"); }(), 4);
}
Run Code Online (Sandbox Code Playgroud)

您可能想测试比true.
在这种情况下,您必须解决(让我说)当前 lambda 定义的限制(对于该限制,布尔值既不能捕获也不能作为参数传递)。
具有非类型模板参数的函数模板可以完成这项工作。举个例子:

template<bool b>
void f() {
    int c = ([](){ static_assert(b, "!"); }(), 4);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

优化后,使用 lambda 的生成代码不会有太大差异(您可以使用这些最小示例在godbolt上轻松检查它)。