<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/81232>81232</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Can't swap two std::hash<T*>
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ostash
</td>
</tr>
</table>
<pre>
For the following code snippet:
```c++
#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_;
};
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);
}
```
`clang -std=c++20` returns:
```console
In file included from <source>:2:
In file included from /opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/vector:66:
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/stl_vector.h:139:4: error: no matching constructor for initialization of '_Tp_alloc_type' (aka 'MyAllocator<int>')
139 | : _Tp_alloc_type()
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/stl_vector.h:312:7: note: in instantiation of member function 'std::_Vector_base<int, MyAllocator<int>>::_Vector_impl::_Vector_impl' requested here
312 | _Vector_base() = default;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/stl_vector.h:528:7: note: in defaulted default constructor for 'std::_Vector_base<int, MyAllocator<int>>' first required here
528 | vector() = default;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:1246:60: note: in defaulted default constructor for 'std::vector<int, MyAllocator<int>>' first required here
1246 | decltype(__helper<const _Tp&>({}))* = 0);
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:1255:24: note: while substituting deduced template arguments into function template '__test' [with _Tp = std::array<std::vector<int, MyAllocator<int>>, 1>]
1255 | typedef decltype(__test(declval<_Tp>())) type;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:1260:14: note: in instantiation of template class 'std::__is_implicitly_default_constructible_impl<std::array<std::vector<int, MyAllocator<int>>, 1>>' requested here
1260 | : public __is_implicitly_default_constructible_impl<_Tp>::type
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:161:30: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
161 | __enable_if_t<bool(_Bn::value)>...>;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:161:30: note: in instantiation of template class 'std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int>>, 1>>' requested here
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:177:16: note: while substituting explicitly-specified template arguments into function template '__and_fn'
177 | : decltype(__detail::__and_fn<_Bn...>(0))
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/type_traits:182:29: note: in instantiation of template class 'std::__and_<std::__is_implicitly_default_constructible<const int>, std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int>>, 1>>>' requested here
182 | : __bool_constant<!bool(_Pp::value)>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/stl_pair.h:247:16: note: in instantiation of template class 'std::__not_<std::__and_<std::__is_implicitly_default_constructible<const int>, std::__is_implicitly_default_constructible<std::array<std::vector<int, MyAllocator<int>>, 1>>>>' requested here
247 | explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
| ^
<source>:33:3: note: in instantiation of template class 'std::pair<const int, std::array<std::vector<int, MyAllocator<int>>, 1>>' requested here
33 | swap(h1, h2);
| ^
<source>:13:3: note: candidate constructor not viable: requires single argument 's', but no arguments were provided
13 | MyAllocator(Storage* s);
| ^ ~~~~~~~~~~
<source>:16:3: note: candidate constructor template not viable: requires single argument 'other', but no arguments were provided
16 | MyAllocator(MyAllocator<U> const& other) noexcept;
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:7:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
7 | class MyAllocator
| ^~~~~~~~~~~
<source>:7:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
7 | class MyAllocator
| ^~~~~~~~~~~
1 error generated.
Compiler returned: 1
```
when libstdc++ >= 12 is used.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcWU9z6jgS_zTi0gVlS4DNgQOBpHYPU7VV-3auLtlusPYJySvJJJnDfPYtyX8whOQl83bmvSxFOUFSt7p__Vcyt1YcFOKaLO7IYjfhjau0WWvruK0muS6f1w_agKsQ9lpK_SjUAQpdIlgl6hodYRsS7UjUP5dR-y0IvfPfdpQyoQrZlAiEbbkx_Jmw-1tzJyycNufJ8Cwktxb-6bThByTsbjzn8FhL7gKxe65R8SPCl4FBS_rL80ZKXXCnDXTEScelbnIpikELgMZ6FU9cNph5hkDYzjO8u1xQa6Ecmm6Wbq7EGm9JaNrLTjdgCV1dL4abWvxr0OKK2_gX2_plUGhlHaFL0K5CQ-gKlManAmv3Yi8vLfCWARKagnWl159trPgNMwcKxiICnLQoocQRSWBRE7r9Bm0HsREnT3fGeAxHdl6d7K4ow85PhKZeocFkvQnOez_yeiQvwOW6X55_xSIYaqDo3WwrlPNqXCLqB9l9-PZMe04bY14w6_x5G_bx3OIL0oH2b9xWl5QVtxVh2-F3zYXfPxgTzqKFPT1P72b3NzXtuFexJ6noeU3AhqbDxNg6ye4qaK8iuZBcHWAaxNt1AU39OjDoGqPsq8GvldUS29G_K9gLidBFeQl7o4_e0a1uTIFBow0dWL2ynD7o2hH6UOhjLSSaKT7VUhvv6w-HopjGbEZnEaEPUuTtEKEPT-kyW86nUqjmaXpQDaEPw7rZ7OWj29Nv06WvEUHvM5vl8qz3jxcrF84S-mCdzFoJZxVhm5itCNvMCdsAGhPEBqXhyF1RtSlcWWcavx722oBQwgkuxW_cCa1A74HQJPtSZyHqQyIkNAFCU_6V-7mbEUMT71-dS8bMx-wW-o8X4ZpjOlof1iRbIIv7nxxcFnt3TVpMQ2IDoUAo67hyYkDwiMccDewbVYQhQpMh0rNfA7ss5xbfkYbGJOJYyxsjNAGD_2nQOiyhQoM9riymAdeLLbuUynZQ4p430l1klc9iiAVNbxii0wjL_r8X3v7HLUET2AtjXcBamCuoFzQduXyXMD4b1D4yM2e4R5xtYjr36W4ZfRfI7623b8LrRQlolVjILn9kWYWyxnPVzL7UhC4Dr9R3DMnOpxj_3QQbRJe9zWcwwGLhC-R8bIDHypdI2-TWCdc4n9FLLJsCy3Mryc2hOaJy1ncS-pyGzr0mTbLMoe8bEyCLu0fhKo_f7e7m47bsGqHFbrDfYjEKD69miftLa7bipH7sxCVhW2_P1pidGVeB8JOZMIRPPP9WxRhM0x5bLtJUJmxI9KIQTj5nXdRlQ9SJXGJXG7b_O-O1MXmzsHitBnN6jdqjFHxI0s68QbZg189j1GXsW4GLvEhoar-KuvbxyHxCdPgU4g9yXnx1hvt29w4aizDd98aeDnNTKY7CEbaLwGmwiP6YNu6olnFbyTNUPIC4zxxh21xr6aPnTnVG9ofXkOfuZ7PZ9ZHhMwL7ZwTLXxQnPx--SRJQ_kY98VK28E1tjYXYi48XF67KbK9CeeldOEkucsZF8i_RcdH3tj0x22Z3qnNjmkZdGfg83pz6s4KPxe_wZg_F2Dvf69_ni4TWVX9sgLxRSyBO6YVfZJlPaq083DPbEhr3ee4f9Ys89zM7xOjsUnPRnlzo_GUQftgtlHZXbvF_4yhv-Qqdtzmkz1Ahd3RYDBC8V_DsS9zu_roHXd5UMeYf32G3W5d8f0nDBsBYF2Rv3AqeEYBXMYhfYFBwVYoyKDw6Birt4CR4QHrTn-ksWKEO8lxDAjrh7mgLeeNA6VF5eUSDUBt9EiWWg4Rxr8j7rtmvdILfh89t9ZbvU28w8vv17K7nP6Tr8qauf-wlwAiE8-f31z838UmuL11uw0No6iqEPgih0PXzeEEr4E3k4gGVHqjoFXSgzQWvvee5iOc_R62jPuGPU6v776VycXvxCwdUaLjDctaOb7s62N3ho88zEL_xIuCxQgVS5NaVXXGDgNcOYgrC-tNMOZuUa1au2IpPcB0nUTJfLlareFKtMY8ojWM2X-YRX-SLJU1Zkublooj3EStXE7GmEZ1HNFpFabRk8WzPYz5fRknBlvMowQWZR3jkQs6kPB1n2hwmwtoG12lMGZ1InqO04fUlpQofIUwSSsliNzFrTzPNm4Ml80gK6-yZixNO4nrLfX_qQkYE96hfvJxpX-7dTxoj15VzdXjpQR98qyBc1eSzQh999yBP_Z9pbfS_sfBNRxDGF_8g7H8DAAD__6oszWo">