繁体   English   中英

如何实现 std::lcm 以符合标准?

[英]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)不允许模板参数。

这不是如何告诉 static_assert constexpr 函数参数是 const 的副本? ,同理。

我能做到的最好的是:

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM