https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92679
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- Non-preprocessed testcase: #include <iostream> #include <typeindex> #include <functional> #include <any> #include <unordered_map> template <typename TReturn> struct any_visitor { using function = std::function<TReturn(std::any &)>; std::unordered_map<std::type_index, function> functions; template <typename TArg> void accept(std::function<TReturn(TArg &)> f) { functions.insert(std::make_pair(std::type_index(typeid(TArg)), function([&f](std::any &x) -> TReturn { return f(std::any_cast<TArg &>(x)); }))); } TReturn operator()(std::any &x) { try { auto function = functions.at(std::type_index(x.type())); return function(x); } catch (...) { throw std::runtime_error("No visitor registered"); } } }; int main() { auto visitor = any_visitor<std::string>(); visitor.accept<int>([](int x) { return std::to_string(x); }); visitor.accept<double>([](double x) { return std::to_string(x); }); visitor.accept<std::string>([](std::string &x) { return x; }); visitor.accept<std::vector<double>>( [](std::vector<double>&) { return "VECTOR"; }); std::any x; x = 1; std::cout << visitor(x) << "\n"; x = 1.; std::cout << visitor(x) << "\n"; x = std::string("STRING"); std::cout << visitor(x) << "\n"; x = std::vector<double>{0., 1., 2., 3., 4., 5.}; std::cout << visitor(x) << "\n"; } The bug is here: void accept(std::function<TReturn(TArg &)> f) { functions.insert(std::make_pair(std::type_index(typeid(TArg)), function([&f](std::any &x) -> TReturn { ^^^^ You're binding a reference to a function parameter, which goes out of scope as soon as the function returns. When you later invoke the std::function it uses a dangling reference.