[英]How to implement std::lcm to be standard conform?
我正在尝试实现 std::lcm 并且我需要static_assert
参数或结果在标准要求的范围内:
如果 |m|、|n| 或 |m| 的最小公倍数,则行为未定义和 |n| 不能表示为 std::common_type_t<M, N> 类型的值。
简化问题是这样的:假设我有以下代码:
constexpr void foo(int x) noexcept {
if consteval {
static_assert(x == 0, "x must be 0");
}
}
编译 c++23 给出:
<source>: In function 'costexpr void foo(int) noexcept':
<source>:3:25: error: non-constant condition for static assertion
3 | static_assert(x == 0, "x must be 0");
| ~~^~~~
<source>:3:25: error: 'x' is not a constant expression
我如何静态断言 x == 0? 或显示错误消息的等效项。
注意:这不是consteval 允许在函数参数上使用 static_assert 的副本吗? 因为 noexcept 不能抛出。
这不是使用 C++20 概念的 static_assert 编译时参数检查的重复,因为用例(实现 std::lcm)不允许模板参数。
我能做到的最好的是:
#include <cstdlib>
constexpr int foo(int x) noexcept {
if consteval {
if (x !=0) {
std::abort(); // "x must be 0"
}
}
return x;
}
constinit int x = foo(1);
constinit int y = foo(0);
这会生成冗长的错误输出:
<source>:12:15: error: variable does not have a constant initializer
constinit int x = foo(1);
^ ~~~~~~
<source>:12:1: note: required by 'constinit' specifier here
constinit int x = foo(1);
^~~~~~~~~
<source>:6:13: note: non-constexpr function 'abort' cannot be used in a constant expression
std::abort(); // "x must be 0"
^
<source>:12:19: note: in call to 'foo(1)'
constinit int x = foo(1);
^
/usr/include/stdlib.h:591:13: note: declared here
extern void abort (void) __THROW __attribute__ ((__noreturn__));
^
"x must be 0"
非常隐蔽,我对此并不满意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.