使用static_assert()

时间:2016-11-17 17:25:34

标签: 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?
}

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

3 个答案:

答案 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);