问题标签 [consteval]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
256 浏览

c++ - 编译时初始化一个非常量变量

问题: 如何在编译时使用函数初始化非常量变量,同时仍然启用对所述函数的运行时调用?

详细信息:我正在使用 C++20,并且我有以下代码:

A 预期,上述代码编译,diag 在编译时执行,M 为常量。如果我将呼叫线路更改为

代码再次编译,但这次 diag 在运行时执行,并且 M 不是常量。

我想将以上两者结合起来:在编译​​时执行 diag,但保持 M 可变;基本上是在编译时用一些复杂的东西初始化一个非常量变量,比如 diag 的返回值。

方法:我将代码更改为

这一次,M 是非常量的,而 diag 是在编译时执行的,所以我的目标有效地实现了。我的问题是:consteval必须在编译时执行,所以如果我想在运行时代码的其他地方使用 diag,我将不得不编写另一个函数。

这导致了一个问题: 如何在编译时使用函数初始化非常量变量,同时仍然启用对所述函数的运行时调用?

注意: 在上面的示例代码中,diag 创建了一个具有给定条目的对角矩阵。我希望代码等效于

这里,M 不是一个常数,而是从一个常数的、编译时确定的对角矩阵分配的。

0 投票
3 回答
273 浏览

c++ - 如何使 consteval 函数失败?

我有以下功能:

该函数应该失败而不是返回默认值,但我不能抛出异常或调用assert。我可以在static_assert对函数的每次调用中添加一个(使用宏会不那么可怕),但我更喜欢在函数中工作的解决方案。在这种情况下有没有办法触发编译失败?

0 投票
1 回答
114 浏览

c++ - 如何在 C++20 中将复杂的数据结构序列化为编码的 constexpr 初始化

目标是将大型数据结构序列化为constexpr初始化,因此它们将成为.textor.rodata段的一部分,并可用于constevalconstexpr

数据结构包含用于交叉引用/索引等的容器。所有这些代码都将生成,因此我们可以使用相同或等效的容器逻辑在代码生成器内计算容器状态,然后按原样序列化容器状态。

C++ 不支持constexpr.

“在 Kona 2019 中,这种方法被认为过于脆弱,因此非瞬态分配被从功能集中移除。” http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p0784r7.html

因此,使用std::或自制动态容器是不可能的。

(可变参数?)模板的使用似乎也是不可能的,因为数据结构必须以运行时动态方式可用,即任何模板的使用都需要在顶部有一个类型擦除层,这看起来很笨拙。见https://www.artima.com/articles/on-the-tension-between-object-oriented-and-generic-programming-in-c

正如这里所探讨的,下一次尝试是尝试序列化为复合文字。请参阅https://en.cppreference.com/w/c/language/compound_literal

标准 C++20 实际上并没有正式支持复合文字,但我们可以依靠编译器扩展来支持 C++ 中的这个 C 特性。似乎在所有主要的 C++ 编译器中都可用。

下面的示例只是一个非常小的概念证明(或尝试这样做)。

问题:以下适用于 Clang 但不适用于 GCC。为什么?有不同的方法吗?

在 GCC 上,这失败了。

在这里探索它:

https://godbolt.org/z/nMKnoY6fY

0 投票
1 回答
1242 浏览

c++ - 如果需要 consteval 怎么办?

C++23 将引入if consteval. 这将在哪里使用,它与 有何不同constexpr if

0 投票
2 回答
143 浏览

c++ - 是否可以使用非常量引用参数调用 consteval 函数?

如果我正确理解了规则immediate functions,则以下是合法用法:

可以调用这个函数吗?我找不到任何方法来consteval强制它必须在编译时表达式中调用,但int& a由于缺少const. 还有其他我想念的方式吗?

0 投票
1 回答
106 浏览

c++ - 将 constexpr 更改为 consteval 会导致 MSVC 中出现无法理解的错误消息。编译器错误或有问题的代码?

我有以下模板/编译时实用程序帮助函数。当一切正常时,它在所有三个编译器(MSVC、GCC、clang)中都可以正常工作constexpr,但是更改一些位会consteval导致 MSVC 出现奇怪的错误。我想尽可能地迁移我所有的constexpr机器consteval,这个问题没有帮助。

错误信息是:

我根本没有看到任何聚合初始化optional。我的问题是:您认为这是 MSVC 中的错误,还是我的代码有问题?

PS Removing optionaland just returnsize_t删除了错误,但我确实需要一种方法来说“包中不存在该类型”而不会出现编译错误。std::optional在语义上似乎非常适合这个。

0 投票
1 回答
138 浏览

c++ - 为什么 consteval/constexpr 和模板元函数之间的编译时间有如此大的差异?

我很好奇就编译时评估而言,我可以将 gcc 推到多远,所以我让它计算Ackermann函数,特别是输入值为 4 和 1(任何高于此值都是不切实际的):

(我认为递归深度限制在~16K,但为了安全起见,我用它编译了这个-std=c++20 -fconstexpr-depth=100000 -fconstexpr-ops-limit=12800000000

毫不奇怪,这会占用大量的堆栈空间(事实上,如果以 8mb 的默认进程堆栈大小运行,它会导致编译器崩溃)并且需要几分钟的时间来计算。然而,它最终会到达那里,所以编译器可以处理它。

之后,我决定尝试使用模板、元函数和部分特化模式匹配来实现 Ackermann 函数。令人惊讶的是,以下实现只需要几秒钟即可评估:

(用 编译-ftemplate-depth=17000

为什么评估时间会有如此巨大的差异?这些本质上不是等效的吗?我想我可以理解consteval需要更多内存和评估时间的解决方案,因为它在语义上由一堆函数调用组成,但这并不能解释为什么在运行时计算的这个完全相同的(非 consteval)函数只需要比元函数版本(编译时没有优化)。

为什么consteval这么慢?我几乎很想得出结论,它正在由 GIMPLE 解释器或类似的东西进行评估。还有,元功能版怎么会这么快?它实际上并不比优化的机器代码慢多少。

0 投票
0 回答
123 浏览

c++ - 无法在编译时将数组转换为字符串视图

我试图std::string_view在编译时将 1 个字符转换std::string_viewconstexpr.

考试:

这是char_to_string函数的定义:

我尝试了不同的构造函数std::string_view,但它们都不起作用:

constexpr basic_string_view(const CharT* s, size_type count)

原始数组:
std::array

constexpr basic_string_view(const CharT* s)

原始数组:
std::array

constexpr basic_string_view(It first, End last)

原始数组:
std::array

constexpr basic_string_view(R&& r)

好吧,这是 C++ 23 的补充,并且 libstdc++ 已经实现了它。

原始数组:
std::array

所有这些都将失败并共享一个常见的编译器错误:

  • std::string_view{...}不是常量表达式

我不知道为什么,但是所有std::string_view构造函数都已声明constexpr并且std::array已经声明,constexpr并且我还将原始数组声明为constexpr.

0 投票
1 回答
87 浏览

c++ - 在 C++20(在源位置示例)中,立即函数的哪个上下文默认参数被替换?

在 C++20 中添加了一个新功能来获取源位置信息:https ://en.cppreference.com/w/cpp/utility/source_location

这是该页面的一个稍作修改的示例,其中使用了添加立即函数loc来获取源位置:

在最新的 MSVC 2019 中,它的打印结果与 cppreference.com 的原始示例一样:

但在 GCC 中,同一行在输出中显示了两次:

演示:https ://gcc.godbolt.org/z/nqE4cr9d4

哪个编译器在这里?

如果定义loc函数不是立即函数:

然后 GCC 的输出发生变化并类似于原始示例:

虽然 MSVC 拒绝编译它并出现错误:

演示:https ://gcc.godbolt.org/z/vorW4f9ax

还请建议,哪个编译器在非即时情况下也是正确的?

0 投票
1 回答
74 浏览

c++ - 立即函数作为 Clang++ 中的默认函数参数初始化器

如果使用立即函数(用 声明consteval)来默认初始化全局函数参数,如这里

然后 Clang 编译器发出错误:

当其他编译器接受代码时,演示:https ://gcc.godbolt.org/z/z8h7MPaGx

假设代码格式正确并且只是一个 Clang 错误是否正确?有什么已知的解决方法吗?