带 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);