我在下面有這段代碼,它遞回地遍歷圖的節點(為簡單起見,這里只顯示了邊)。我希望函式的結果與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;
}
編譯器資源管理器
uj5u.com熱心網友回復:
MSVC 處理視圖的方式似乎存在問題。這是一個在沒有視圖的情況下作業的有點難看但等效的代碼:
#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;
}
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/515296.html
上一篇:在建構式中使用const靜態陣列會導致“警告...在此函式中未初始化”
下一篇:如何給全域回呼函式一個本地實體?
