<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/65007>65007</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
std::ranges::set_union won't compile with custom projections of different types
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
eprstov
</td>
</tr>
</table>
<pre>
the following code doesn't compile
```cpp
#include <algorithm>
#include <string>
#include <vector>
struct S
{
int i;
std::string s;
};
struct M
{
M(int);
M( const S& );
};
auto set_union( const std::vector<int>& vi, const std::vector<S>& vs )
{
std::vector<M> vm;
std::ranges::set_union( vi, vs, std::back_inserter(vm), std::less{}, std::identity{}, &S::i );
return vm;
}
```
the implementation of `std::ranges::set_union` simply forwards to `std::set_union` providing a comparison wrapper like this
```cpp
auto __ret = std::__set_union<_RangeAlgPolicy>(
ranges::begin(__range1),
ranges::end(__range1),
ranges::begin(__range2),
ranges::end(__range2),
std::move(__result),
ranges::__make_projected_comp(__comp, __proj1, __proj2));
```
the comparison operation in `std::set_union`, like in any algorithm, is called both ways:
```cpp
__comp(*__it1, *__it2)
```
and
```cpp
__comp(*__it2, *__it1)
```
which makes the wrapper apply `__proj1` to both `*__it1` and `*__it2`. the same is true for `__proj2`. it causes no problem if both projections are `std::identity` but won't compile with custom projections.
`std::ranges::merge` compiles just fine in this case.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVdGOozoM_Zr0xdoKQgvlgYfZzvZtpKs7H4ACuJCdkKDEtOrfXwVogZ3p7l6polFsnxwf24lwTtYaMWP772z_uhE9NcZm2FlH5rIpTHXLqEE4G6XMVeoaSlMhVAadZjwhKE3bSYUseGXBy_SNg_FXdt20wyOpS9VXCCw6ClUbK6lpWfTjK7sjK3X9xHjBkoydjcPXke1LgvdpL_k-LgAApCaQLFrsOKpY9MKil_EccA8rS17n9RL47VfgN8YPUhPj6Qrab0NptPNceAxL-2dw0ZMBh5T3Who9hz4I3nM9-qOiHx7xIhk_PvV7v3u54ejPanwOeWPRD7i0Xytkha7RTWotiY40Ls5_H96FKD9yqR1aQsv44dJ6EksPhc55PsnraltWqEnSbTYxHr9PtrWID44Wqbd6ydyHrvtvGeObWLadwhY1CZJGgzkDi4M_JBsH4HzcDc7GXoWtHJBZxa18O2susvJtJYbREFY6o-FqRdehBSU_EKiR7tmkDD2R5xYJWPQ6S5Tn8zHRMf_Xc31R9T9GyfI2VP0wabNMo8Ba-nrl-bAbjvWYRRyEXPijrp55_waW_y_YtfcjwdZccHRC1yv6E2Set-ID886an1gSVrkXe4gfF0fIB2M4L8eDF720bhPfIIuKmQ7t2CZSPy23Bx9KKjUIfYP5ZuNHkA5KoRRWUBhq4CpuA_cnhb8TPzD-kueSwnEMhjWfh3nNWejqb_H4Ai98hjd-r40sG_D6OvCq3JtXdH4MWBzcpY0DPwtDdoMYE3gcgNDVYouzONgOUE606IUh2_s3xc5oo48kKEXv0IE2fpYKhS3I83jGVGxptANhcVWVxxUSB1D0BFezep7gKqmBsndk2iXO9pd368vLoEVboweewBz87B3BWeqh8H6coRQOt5sqi6o0SsUGszBOo2AXpzzZNJnYh3gOz0WwOxzSfXpOUKTIwyhJcJfG-2ojMx7wKDjwOAx2h12yDTGKi0NQ8jBN0igN2S7AVki1VerSbo2tN9K5HrN4HwTJRokClbu_4TbzTt-KvnZsFyjpyM1hJElh9vtL72_V8zdoJc9ntKgJ6Nah2_RWZQ1RN2DyE-OnWlLTF9vStIyfPI_p79uExPhpyMUxfhrS-S8AAP__QniLHA">