有什么办法可以将 static_assert 插入 ISO C++11 中的表达式中吗?

Is there any way to slip a static_assert into an expression in ISO C++11?

在C++11中这样写是合法的,例如:

int b = (some_function_returning_void(), 1020);

你会得到 1020。但它不会让你写:

int b = (static_assert(2 > 1, "all is lost"), 304);

documentation explains the legal spots where static_assert (a keyword, 显然) 可以发生:

A static assert declaration may appear at block scope (as a block declaration) and inside a class body (as a member declaration)

我试了几次才成功:

int b = ({static_assert(2 > 1, "all is lost"); 304;});

但是 -Wpedantic 我得到 "warning: ISO C++ forbids braced-groups within expressions"。有趣的是,这些被称为 "statement expressions" 和 used in the Linux kernel.

但假设我想留下来 -Wpedantic。是否有任何干净的解决方法?

static_assert 不是一个表达式(不像sizeof),所以你不能使用它需要表达式的地方。

它甚至不是 void 类型的表达式(有趣的是,throwvoid 类型的表达式)所以你甚至不能在三元中使用它。

语句表达式 不是标准的 C++,所以我建议不要使用它们。

一个 lambda

int b = []{
    static_assert(2 > 1, "all is lost"); return 304;
}();

int b = ([]{static_assert(2 > 1, "all is lost");}, 304);

几乎不干净。 (第二个 lambda 看起来离未定义只有一步之遥)。

正如@dyp 在评论中提到的,您可以滥用逗号运算符和 lambda 表达式:

([]{static_assert(true,"");}, 42)

Live on Coliru

函数模板呢:

template<int T> void my_static_assert()
{
    static_assert(T, "asserted");
}

那么你就可以使用逗号操作符了,你甚至不需要调用函数:

int x = (my_static_assert<(2 > 1)>, 2001);

也许您在这里和那里需要一些括号来使解析器满意。你丢失了静态断言消息,但它有效。