Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] try_emplace() method report overloaded ambiguous with gcc 8.3 #125

Open
lrita opened this issue Aug 30, 2024 · 0 comments
Open

[BUG] try_emplace() method report overloaded ambiguous with gcc 8.3 #125

lrita opened this issue Aug 30, 2024 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@lrita
Copy link

lrita commented Aug 30, 2024

Describe the bug

using try_emplace(Key &&) rvalue method is compiled failed with transparent/heterogeneous-accessible map.

To Reproduce

  1. add code in test/unit/transparent.cpp
TEST_CASE_MAP("transparent_rvalue", std::string, size_t, string_hash, string_eq) {
    auto map = map_t();
    std::string key = "abc";
    size_t value = 0;
    map.try_emplace(std::move(key), std::move(value));
}
  1. usng gcc 8.3
source scl_source enable devtoolset-8
export PATH=/opt/rh/devtoolset-8/root/usr/bin:$PATH
  1. compile failed.
[46/69] Compiling C++ object test/udm-test.p/unit_transparent.cpp.o
FAILED: test/udm-test.p/unit_transparent.cpp.o
c++ -Itest/udm-test.p -Itest -I../test -I../include -I../subprojects/doctest-2.4.9/doctest -I/data1/conda/envs/neal/include -fdiagnostics-color=always -DNDEBUG -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -Werror -std=c++17 -O0 -g -DANKERL_UNORDERED_DENSE_HAS_BOOST=1 -DFMT_SHARED -pthread -Wno-stringop-overflow -Wshadow=global -Wno-array-bounds -Wconversion -Wextra -Wunreachable-code -Wuninitialized -pedantic-errors -Wno-unused-function -MD -MQ test/udm-test.p/unit_transparent.cpp.o -MF test/udm-test.p/unit_transparent.cpp.o.d -o test/udm-test.p/unit_transparent.cpp.o -c ../test/unit/transparent.cpp
../test/unit/transparent.cpp: In instantiation of ‘void DOCTEST_ANON_TMP_11() [with map_t = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, false>]’:
../test/unit/transparent.cpp:274:1:   required from ‘{anonymous}::DOCTEST_ANON_TMP_11ITERATOR<std::tuple<_El0, _El ...> >::DOCTEST_ANON_TMP_11ITERATOR(const char*, unsigned int, int) [with Type = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, false>; Rest = {ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>, deque_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::deque<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> > >, ankerl::unordered_dense::v4_4_0::bucket_type::standard>}]’
../test/unit/transparent.cpp:274:1:   required from here
../test/unit/transparent.cpp:281:5: error: call of overloaded ‘try_emplace(std::remove_reference<std::basic_string<char>&>::type, std::remove_reference<long unsigned int&>::type)’ is ambiguous
     map.try_emplace(std::move(vvv), std::move(ooo));
     ^~~
In file included from ../test/unit/transparent.cpp:1:
../include/ankerl/unordered_dense.h:1573:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(const Key&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char>, long unsigned int>*, std::vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > > >]’
     auto try_emplace(Key const& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1578:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(Key&&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char>, long unsigned int>*, std::vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > > >]’
     auto try_emplace(Key&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1600:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(K&&, Args&& ...) [with K = std::basic_string<char>; Args = {long unsigned int}; Q = long unsigned int; H = string_hash; KE = string_eq; typename std::enable_if<((is_map_v<Q> && is_transparent_v<H, KE>) && is_neither_convertible_v<K&&, typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>), bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char>, long unsigned int>*, std::vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > > >]’
     auto try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../test/unit/transparent.cpp: In instantiation of ‘void DOCTEST_ANON_TMP_11() [with map_t = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>]’:
../test/unit/transparent.cpp:274:1:   required from ‘{anonymous}::DOCTEST_ANON_TMP_11ITERATOR<std::tuple<_El0, _El ...> >::DOCTEST_ANON_TMP_11ITERATOR(const char*, unsigned int, int) [with Type = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>; Rest = {deque_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::deque<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> > >, ankerl::unordered_dense::v4_4_0::bucket_type::standard>}]’
../test/unit/transparent.cpp:274:1:   required from ‘{anonymous}::DOCTEST_ANON_TMP_11ITERATOR<std::tuple<_El0, _El ...> >::DOCTEST_ANON_TMP_11ITERATOR(const char*, unsigned int, int) [with Type = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, false>; Rest = {ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>, deque_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::deque<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> > >, ankerl::unordered_dense::v4_4_0::bucket_type::standard>}]’
../test/unit/transparent.cpp:274:1:   required from here
../test/unit/transparent.cpp:281:5: error: call of overloaded ‘try_emplace(std::remove_reference<std::basic_string<char>&>::type, std::remove_reference<long unsigned int&>::type)’ is ambiguous
     map.try_emplace(std::move(vvv), std::move(ooo));
     ^~~
In file included from ../test/unit/transparent.cpp:1:
../include/ankerl/unordered_dense.h:1573:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(const Key&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = true; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = ankerl::unordered_dense::v4_4_0::segmented_vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, 4096>::iter_t<false>]’
     auto try_emplace(Key const& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1578:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(Key&&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = true; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = ankerl::unordered_dense::v4_4_0::segmented_vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, 4096>::iter_t<false>]’
     auto try_emplace(Key&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1600:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(K&&, Args&& ...) [with K = std::basic_string<char>; Args = {long unsigned int}; Q = long unsigned int; H = string_hash; KE = string_eq; typename std::enable_if<((is_map_v<Q> && is_transparent_v<H, KE>) && is_neither_convertible_v<K&&, typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>), bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::allocator<std::pair<std::basic_string<char>, long unsigned int> >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = true; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = ankerl::unordered_dense::v4_4_0::segmented_vector<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, 4096>::iter_t<false>]’
     auto try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../test/unit/transparent.cpp: In instantiation of ‘void DOCTEST_ANON_TMP_11() [with map_t = deque_map<std::basic_string<char>, long unsigned int, string_hash, string_eq>]’:
../test/unit/transparent.cpp:274:1:   recursively required from ‘{anonymous}::DOCTEST_ANON_TMP_11ITERATOR<std::tuple<_El0, _El ...> >::DOCTEST_ANON_TMP_11ITERATOR(const char*, unsigned int, int) [with Type = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>; Rest = {deque_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::deque<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> > >, ankerl::unordered_dense::v4_4_0::bucket_type::standard>}]’
../test/unit/transparent.cpp:274:1:   required from ‘{anonymous}::DOCTEST_ANON_TMP_11ITERATOR<std::tuple<_El0, _El ...> >::DOCTEST_ANON_TMP_11ITERATOR(const char*, unsigned int, int) [with Type = ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char>, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char>, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, false>; Rest = {ankerl::unordered_dense::v4_4_0::detail::table<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> >, ankerl::unordered_dense::v4_4_0::bucket_type::standard, true>, deque_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int, string_hash, string_eq, std::deque<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, long unsigned int> > >, ankerl::unordered_dense::v4_4_0::bucket_type::standard>}]’
../test/unit/transparent.cpp:274:1:   required from here
../test/unit/transparent.cpp:281:5: error: call of overloaded ‘try_emplace(std::remove_reference<std::basic_string<char>&>::type, std::remove_reference<long unsigned int&>::type)’ is ambiguous
     map.try_emplace(std::move(vvv), std::move(ooo));
     ^~~
In file included from ../test/unit/transparent.cpp:1:
../include/ankerl/unordered_dense.h:1573:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(const Key&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::deque<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = std::_Deque_iterator<std::pair<std::basic_string<char>, long unsigned int>, std::pair<std::basic_string<char>, long unsigned int>&, std::pair<std::basic_string<char>, long unsigned int>*>]’
     auto try_emplace(Key const& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1578:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(Key&&, Args&& ...) [with Args = {long unsigned int}; Q = long unsigned int; typename std::enable_if<is_map_v<Q>, bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::deque<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = std::_Deque_iterator<std::pair<std::basic_string<char>, long unsigned int>, std::pair<std::basic_string<char>, long unsigned int>&, std::pair<std::basic_string<char>, long unsigned int>*>]’
     auto try_emplace(Key&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
../include/ankerl/unordered_dense.h:1600:10: note: candidate: ‘std::pair<typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, bool> ankerl::unordered_dense::v4_4_0::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, IsSegmented>::try_emplace(K&&, Args&& ...) [with K = std::basic_string<char>; Args = {long unsigned int}; Q = long unsigned int; H = string_hash; KE = string_eq; typename std::enable_if<((is_map_v<Q> && is_transparent_v<H, KE>) && is_neither_convertible_v<K&&, typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer, 4096>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>), bool>::type <anonymous> = 1; Key = std::basic_string<char>; T = long unsigned int; Hash = string_hash; KeyEqual = string_eq; AllocatorOrContainer = std::deque<std::pair<std::basic_string<char>, long unsigned int>, std::allocator<std::pair<std::basic_string<char>, long unsigned int> > >; Bucket = ankerl::unordered_dense::v4_4_0::bucket_type::standard; bool IsSegmented = false; typename std::conditional<is_map_v<T>, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::iterator, typename std::conditional<is_detected_v<ankerl::unordered_dense::v4_4_0::detail::detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, typename std::conditional<IsSegmented, ankerl::unordered_dense::v4_4_0::segmented_vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer>, std::vector<typename std::conditional<is_map_v<T>, std::pair<_T1, _T2>, Key>::type, AllocatorOrContainer> >::type>::type::const_iterator>::type = std::_Deque_iterator<std::pair<std::basic_string<char>, long unsigned int>, std::pair<std::basic_string<char>, long unsigned int>&, std::pair<std::basic_string<char>, long unsigned int>*>]’
     auto try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {
          ^~~~~~~~~~~
  1. gcc 11.2.0 compile ok.

Expected behavior
A clear and concise description of what you expected to happen.

System (please complete the following information):

  • OS: Linux
  • Compiler: g++
  • Version 8.3.1

Additional context

I modify the method with this patch will suppress this fault. Is there a better way to fix it ? Maybe using absl’s key_arg<K> way ?

diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h
index 2aaacd6..d841bad 100644
--- a/include/ankerl/unordered_dense.h
+++ b/include/ankerl/unordered_dense.h
@@ -480,6 +480,14 @@ constexpr bool is_transparent_v = is_detected_v<detect_is_transparent, Hash> &&
 template <typename From, typename To1, typename To2>
 constexpr bool is_neither_convertible_v = !std::is_convertible_v<From, To1> && !std::is_convertible_v<From, To2>;

+template<class T>
+struct remove_cvref
+{
+    using type = std::remove_cv_t<std::remove_reference_t<T>>;
+};
+template< typename T >
+using remove_cvref_t = typename remove_cvref<T>::type;
+
 template <typename T>
 constexpr bool has_reserve = is_detected_v<detect_reserve, T>;

@@ -1595,7 +1603,7 @@ public:
         typename Q = T,
         typename H = Hash,
         typename KE = KeyEqual,
-        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator>,
+        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator> && !std::is_same_v<remove_cvref_t<K>, Key>,
                          bool> = true>
     auto try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {
         return do_try_emplace(std::forward<K>(key), std::forward<Args>(args)...);
@@ -1607,7 +1615,7 @@ public:
         typename Q = T,
         typename H = Hash,
         typename KE = KeyEqual,
-        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator>,
+        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator> && !std::is_same_v<remove_cvref_t<K>, Key>,
                          bool> = true>
     auto try_emplace(const_iterator /*hint*/, K&& key, Args&&... args) -> iterator {
         return do_try_emplace(std::forward<K>(key), std::forward<Args>(args)...).first;
@lrita lrita added the bug Something isn't working label Aug 30, 2024
lrita added a commit to lrita/unordered_dense that referenced this issue Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants