为什么我的 std::variant 的访问者存在堆栈损坏

Why is there stack corruption with my visitor for my std::variant

提问人:Nicolas 提问时间:11/25/2020 最后编辑:Nicolas 更新时间:11/25/2020 访问量:181

问:

我很难理解这段代码发生了什么:


#include <iostream>
#include <variant>

template <class... Ts>
struct overloaded : Ts... {
    using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

struct FirstPSet {
    std::uint16_t uid;
};

struct SecondPSet {
    std::uint16_t uid;
};

using PSet = std::variant<std::monostate, FirstPSet, SecondPSet>;

auto getUID(const PSet& pSet) {
    auto visitor = overloaded{[](const std::monostate&) -> std::uint16_t { return 0; },
                              [](const auto& pSet) -> std::uint16_t { return pSet.uid; }};
    return std::visit(visitor, pSet);
}

int main() {
    FirstPSet pSet{42};

    std::cout << getUID(pSet) << '\n';
}

使用 Visual Studio Community 16.8.2(调试版本)编译时,我在 . 如果我修改为 ,它可以正常工作。getUIDvisitorauto&& visitor = ...

C 工作室 可视化 ++ 堆栈 C++17

评论

1赞 Adrian Mole 11/25/2020
看起来像是一个临时对象的情况,通过强制使用“右值引用”来延长其生存期。不过不确定,我无法在 Windows 10 上使用 VS 16(64 位)重现。visitor
0赞 rm1948 8/4/2021
这适用于 GCC 11 。您可以从 和 lambda 中取出。仅当第一个变体不是默认可构造的时,才需要它。std::monostatetuple
0赞 Fedor 10/10/2021
它在 Visual Studio Community 16.11.2(调试版本)中运行良好,因此看起来编译器错误已得到修复。
0赞 Nicolas 10/12/2021
对我来说,Visual Studio Community 16.11.4 预览版 1 仍然崩溃。
1赞 Nicolas 11/15/2021
似乎是这个错误:developercommunity.visualstudio.com/t/...

答: 暂无答案