https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101049
Bug ID: 101049 Summary: std::variant: missed optimization in std::visit() on more than one variant Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: vermaelen.wouter at gmail dot com Target Milestone: --- // https://godbolt.org/z/T8f89fq1z // -------------------------------------- #include <variant> struct Base {}; struct A : Base { int a; }; struct B : Base {}; struct C : Base {}; struct D : Base {}; using V = std::variant<A, B, C, D>; template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; bool operator==(const V& v1, const V& v2) { return std::visit(overloaded{ [](const A& x, const A& y) { return x.a == y.a; }, [&](const Base&, const Base&) { return v1.index() == v2.index(); } }, v1, v2); } // -------------------------------------- The call to std::visit() is implemented using a table containing 4x4 = 16 function pointers. However 15 out of these 16 sub-functions are identical. It would be nice if these would be shared. Also (before sharing) in these 16 sub-functions the value of a sub-expression like 'v1.index()' could be known during compile-time. It would also be nice if the compiler could exploit this knowledge. So ideally I'd like the compiler to produce only 3 different sub-functions: [](const A& x, const A& y) { return x.a == y.a; }, []() { return true; } []() { return false; } And then fill-in the table with 16 function-pointers to the appropriate of these 3 functions. Thanks.