[Bug libstdc++/126800] New: Heterogeneous insertion into unordered_map doesn't work.

"xbenes3 at fi dot muni.cz via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126800

            Bug ID: 126800
           Summary: Heterogeneous insertion into unordered_map doesn't
                    work.
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xbenes3 at fi dot muni.cz
  Target Milestone: ---

Created attachment 65302
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65302&action=edit
the preprocessed file (*.i*) that triggers the bug

#include <print>
#include <unordered_map>

struct other {};

struct key {
        key() = default;
        key(other) { std::println("key constructed from other"); }
};

struct hash {
        using is_transparent = void;
        auto operator()(auto&&) const noexcept { return 0zu; }
};

struct equal {
        using is_transparent = void;
        auto operator()(auto&&, auto&&) const noexcept { return true; }
};

int main() {
        std::unordered_map<key, int, hash, equal> m{ { key{}, 0 } };
        m.try_emplace(other{}, 0);  // key constructed from other
        m[other{}] = 1;             // key constructed from other
}

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/16/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure
--enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust,cobol
--enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues
--with-build-config=bootstrap-lto --with-gcc-major-version-only
--with-linker-hash-style=gnu --with-system-zlib --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-fixincludes --disable-libssp
--disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.2.1 20260810 (GCC) 

$ g++ -std=c++26 hlookup.cpp
$ ./a.out
key constructed from other
key constructed from other

The expected result was no output at all, because both try_emplace and
operator[] should be heterogeneous (both the hash and the equality function
objects are transparent).

The problem might be in /usr/include/c++/16/bits/hashtable.h on line 1110
(inside try_emplace(const_iterator, _KType&& __k, _Args&&... __args)), where
the code calls _M_locate(__k), but _M_locate only takes const key_type& (the
heterogeneous version is _M_locate_tr).
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.