gpt4 book ai didi

c++ - constexpr 函数在运行时与编译时的不同结果

转载 作者:行者123 更新时间:2023-12-05 04:22:01 25 4
gpt4 key购买 nike

下面这段代码递归地遍历了图的节点(为简单起见,这里只显示了边)。我希望 count_dfs() 函数的结果为 4,无论该函数是在运行时还是编译时求值。

在 MVSC 上,情况并非如此。它在 Clang 和 gcc 上按预期工作,所以我认为这是 MSVC 中的错误。或者代码中有一些UB?据我所知,常量表达式中不允许使用 UB,对吗?是否存在函数在 constexpr 和非 constexpr 执行中产生不同结果的情况?

#include <iostream>
#include <ranges>
#include <array>

struct Edge
{
int from{};
int to{};
};

constexpr auto node_input_edges(auto& edges, int id)
{
return edges | std::views::filter([id](const Edge& e) { return e.to == id; });
}

constexpr void visit_dfs(auto& edges, int curr_node, auto func)
{
for (auto e : node_input_edges(edges, curr_node)) {
visit_dfs(edges, e.from, func);
}
func();
}

constexpr auto count_dfs()
{
std::array<Edge, 3> edges{{{0,2}, {1,2}, {2,3}}};
size_t sz = 0;

visit_dfs(edges, int(edges.size()), [&]() {
++sz;
});
return sz;
}

int main()
{
constexpr auto cnt_ct = count_dfs();
auto cnt_rt = count_dfs();

std::cout << "COMPILE TIME " << cnt_ct << "\n"; // 3 on MSVC, 4 on clang and gcc
std::cout << "RUNTIME " << cnt_rt << "\n"; // 4 on all compilers
return 0;
}

Compiler explorer

最佳答案

这看起来像是 MSVC 如何处理 View 的问题。这是一个有点丑陋但等效的代码,可以在没有 View 的情况下工作:

#include <iostream>
#include <ranges>
#include <array>

struct Edge
{
int from{};
int to{};
};

template<std::size_t n>
constexpr auto node_input_edges(std::array<Edge, n> const& edges, int id)
{
std::array<Edge, n> edges_copy;
auto j = 0;
for (auto i = 0; i < n; ++i) {
if (edges[i].to == id) {
edges_copy[j] = edges[i];
++j;
}
}
if (j != n) {
edges_copy[j] = {0, 0}; // similar to a null terminator
}
return edges_copy;
}

constexpr void visit_dfs(auto const& edges, int curr_node, auto func)
{
for (auto const& e : node_input_edges(edges, curr_node)) {
if (e.from == 0 && e.to == 0) { // check for the null terminator
break;
}
visit_dfs(edges, e.from, func);
}
func();
}

constexpr auto count_dfs()
{
std::array<Edge, 3> edges{{{0,2}, {1,2}, {2,3}}};
size_t sz = 0;

visit_dfs(edges, 3, [&]() {
++sz;
});
return sz;
}

int main()
{
constexpr auto cnt_ct = count_dfs();
auto cnt_rt = count_dfs();

std::cout << "COMPILE TIME " << cnt_ct << "\n";
std::cout << "RUNTIME " << cnt_rt << "\n";
return 0;
}

Demo

关于c++ - constexpr 函数在运行时与编译时的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74090088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com