https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113841
Bug ID: 113841 Summary: Can't swap two std::hash<T*> Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ostash at ostash dot kiev.ua Target Milestone: --- For the following code snippet: --- #include <array> #include <vector> class Storage; template <typename T> class MyAllocator { public: using value_type = T; using pointer = T*; MyAllocator(Storage* s); template <typename U> MyAllocator(MyAllocator<U> const& other) noexcept; T* allocate( std::size_t n ); void deallocate(T* p, std::size_t n ); private: Storage* s_; }; class Foo{ public: Foo(int, int); }; void x() { using std::swap; using MyVec = std::vector<int, MyAllocator<int>>; using MyArrVec = std::array<MyVec, 1>; using MyHash = std::hash<std::pair<const int, MyArrVec>*>; MyHash h1, h2; swap(h1, h2); } --- GCC 12 reports: In file included from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/vector:64, from <source>:2: /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h: In instantiation of 'constexpr std::_Vector_base<_Tp, _Alloc>::_Vector_impl::_Vector_impl() [with _Tp = int; _Alloc = MyAllocator<int>]': /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:312:7: required by substitution of 'template<class _Tp> static std::true_type std::__do_is_implicitly_default_constructible_impl::__test(const _Tp&, decltype (__helper<const _Tp&>(<brace-enclosed initializer list>()))*) [with _Tp = std::array<std::vector<int, MyAllocator<int> >, 1>]' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1249:30: required from 'struct std::__is_implicitly_default_constructible_impl<std::array<std::vector<int, MyAllocator<int> >, 1> >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1253:12: required from 'struct std::__is_implicitly_default_constructible_safe<std::array<std::vector<int, MyAllocator<int> >, 1> >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:167:12: required from 'struct std::__and_<std::__is_constructible_impl<std::array<std::vector<int, MyAllocator<int> >, 1> >, std::__is_implicitly_default_constructible_safe<std::array<std::vector<int, MyAllocator<int> >, 1> > >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1258:12: required from 'struct std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int> >, 1> >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:167:12: required from 'struct std::__and_<std::__is_implicitly_default_constructible<const int>, std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int> >, 1> > >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:178:41: required from 'struct std::__not_<std::__and_<std::__is_implicitly_default_constructible<const int>, std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int> >, 1> > > >' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_pair.h:226:16: required from 'struct std::pair<const int, std::array<std::vector<int, MyAllocator<int> >, 1> >' <source>:38:14: required from here /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/type_traits:1240:58: in 'constexpr' expansion of 'std::vector<int, MyAllocator<int> >()' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:526:7: in 'constexpr' expansion of '((std::vector<int, MyAllocator<int> >*)this)->std::vector<int, MyAllocator<int> >::<anonymous>.std::_Vector_base<int, MyAllocator<int> >::_Vector_base()' /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:139:26: error: no matching function for call to 'MyAllocator<int>::MyAllocator()' 139 | : _Tp_alloc_type() | ^ <source>:16:3: note: candidate: 'template<class U> MyAllocator<T>::MyAllocator(const MyAllocator<U>&) [with T = int]' 16 | MyAllocator(MyAllocator<U> const& other) noexcept; | ^~~~~~~~~~~ <source>:16:3: note: template argument deduction/substitution failed: /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:139:26: note: candidate expects 1 argument, 0 provided 139 | : _Tp_alloc_type() | ^ <source>:13:3: note: candidate: 'MyAllocator<T>::MyAllocator(Storage*) [with T = int]' 13 | MyAllocator(Storage* s); | ^~~~~~~~~~~ <source>:13:3: note: candidate expects 1 argument, 0 provided <source>:7:7: note: candidate: 'constexpr MyAllocator<int>::MyAllocator(const MyAllocator<int>&)' 7 | class MyAllocator | ^~~~~~~~~~~ <source>:7:7: note: candidate expects 1 argument, 0 provided <source>:7:7: note: candidate: 'constexpr MyAllocator<int>::MyAllocator(MyAllocator<int>&&)' <source>:7:7: note: candidate expects 1 argument, 0 provided Compiler returned: 1 Clang 15, 16, 17 also fail to compile with similar error about missing default constructor for custom allocator when they are using libstdc++ >=12 GCC 13 is able to compile this, same as Clang with libc++.