<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62864>62864</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libcxx] std::bind : The args in checking does not match the actual args when calling the functor
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Zeroneplus
</td>
</tr>
</table>
<pre>
In __bind::operator()(), the functor args in __bind_return is _Fd, but in __apply_functor, the actual functor args is _Fd&
```cpp
template<class _Fp, class ..._BoundArgs>
class __bind
: public __weak_result_type<typename decay<_Fp>::type>
{
...
template <class ..._Args>
typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
operator()(_Args&& ...__args)
{
return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
}
...
};
template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
inline _LIBCPP_INLINE_VISIBILITY
typename __bind_return<_Fp, _BoundArgs, _Args>::type
__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
_Args&& __args)
{
return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
}
```
The following sample code will report error when use clang with libcxx, but works normally with gcc and libstdc++
```cpp
#include <functional>
struct some_class {
void operator()(int) && {
}
void operator()() & {
}
};
int main()
{
some_class obj;
auto tmp = std::bind(obj);
tmp();
}
// clang++ tmp.cpp -o main -stdlib=libc++
// report error:
/*
tmp.cpp:16:5: error: no matching function for call to object of type '__bind<some_class &>'
tmp();
^~~
/usr/bin/../include/c++/v1/__functional/bind.h:293:9: note: candidate template ignored: substitution failure [with _Args = <>]: i
mplicit instantiation of undefined template 'std::__bind_return<some_class, std::tuple<>, std::tuple<>, false>'
operator()(_Args&& ...__args)
^
/usr/bin/../include/c++/v1/__functional/bind.h:302:9: note: candidate template ignored: substitution failure [with _Args = <>]: i
mplicit instantiation of undefined template 'std::__bind_return<const some_class, const std::tuple<>, std::tuple<>, false>'
operator()(_Args&& ...__args) const
^
1 error generated.
*/
// g++ tmp.cpp -o main // works normally
```
This maybe the functor arg in __bind_return is _Fd, and in the final ` _VSTD::__invoke(_VSTD::declval<_XFp>(), _VSTD::declval<_XArgs>()...));` will use declval<_Fd>(), which is _Fd&&, does not match the type in __apply_functor, which is _Fd&
```cpp
template <class _Fp, class _BoundArgs, class _TupleUj,
bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
struct __bind_return;
template <class _Fp, class ..._BoundArgs, class _TupleUj>
struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
{
static const bool value = __invokable<_Fp,
typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
};
template <class _Fp, class ..._Args>
using __invokable = __invokable_r<void, _Fp, _Args...>;
template <class _Ret, class _Fp, class ..._Args>
struct __invokable_r
{
static const bool value = type::value;
using type =
typename conditional<
_IsNotSame<_Result, __nat>::value,
typename conditional<
is_void<_Ret>::value,
true_type,
is_convertible<_Result, _Ret>
>::type,
false_type
>::type;
using _Result = decltype(__try_call<_Fp, _Args...>(0));
template <class _XFp, class ..._XArgs>
static auto __try_call(int) -> decltype(
_VSTD::__invoke(_VSTD::declval<_XFp>(), _VSTD::declval<_XArgs>()...));
template <class _XFp, class ..._XArgs>
static __nat __try_call(...);
};
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWFuP4jgW_jXmxSqUciAUDzwABRJSqzWarh317ovlOAY87diR7UDXPsxvX9lOgpNATffualeDEBfH5_odn4uJMfwkGVuB-QbMXyektmelV_9gWklWidpMclW8rw4SYpxzWYB0DdK1qpgmVmmAXgBatp9baM8MHmtJrdKQ6JOBvKXDmtlaS8gNxPvC7c1rGx6TqhLvuCFruRBqayIGzBraDCSvIFmDLAlvWlVhxbKyEsQykG6pIMZtrxzD8Gc6neKNqmWx1icD0l2gaTYG4_wKhBCCdA2rOhecQoyvjHzDmplaWGzfK8fefUlSMlgwSt5BunWS0l3wTtjT8AeLTfgxnU77WsJOTadZTymnQiei50AvyvsPv_kvW1fCaRQYoAygzElKd7CvT8d3hF1E6TXBxP9fRt5obYDNqwET__bl7TXIGMH4gvERez1x7pzuuTYLXBacMtPFTZ_5_ddDO52omx5Hpa9EF93G8Lw1yVE4iUuQbmLzXgcQuZV2xyPQerEVBRbaQsP_ybD1zjzI4nu0rYcyl4JLBvGnw2b7yy_48PnT4fMO_3b4ctgcPh3e_t5IfhwHXoG-6E7CAPk7-DjyDGJ8HHLJepgFyLz7O-DSrTesBeABgHFgDaKqF1H3oonLi_rGQhh5DeKHZd0H_cRsq1ILeKz_MpjQj4EO3hb8Lp3EsL-5hKaEUFcuT9CQshIMUlUweOVCQM0qpS1kWisNr2cmYW2Yw1qe4JXbMxQ8p9-_t-nuqvQ3A6XSJRHiPew4UQqJLNxOYwsK0Ma9IxXGaQ6glEsq6sJHo0eUK0nELef4T2N1TS00qmQ4hF_P6xfFi3Ey4NICtIQNah3BncPymEfD4EPq8Qnj0sKScNmwGYdJZIjKf--dYFJbBW1ZQZC-QmObKuVTOnpxmwcn3pZVI2YcBo2L9wDtA5IBEkczpVUFn5RXEz4ZWwieg_TVgdzDLRDHwQF2e7DZgmXMvs0sgS9I188ZSNdzV3oCTbqG0gmz9OyirwUaHpWGlAgBrXKeYNRCdfT1AgK0aOv0NgYeZf5gLOB9H0TLYL774w_YqVkbDdA-d7Ds3cHZN5EH0L61Ge0vzwDtMY4i0ZMU0zNI12iZgnS9DNa42ryGlMiCFy6bdmmVn6TSzAEHTZ0by20dbCVc1JpBMN_44-JziocZpFtn09zlAMiDwmUlOOWurzCWSMuJ56GOsJYFO3LJiptEgBZdpAxT6811Pp2329oaFJLew_UjEYaN_P1TtXdAB-a7_yYkaYL-cpBQJU2czHxRDWv_B3iC5EcgPTcV4cSkY8iKtq1A_uSP88yjHNM87teNu-Xq7cwNLMl7zoZN-Ec9uCs8XAYKLomAIEse1eHbasGouLhys8VfQ9vbDQAPdt1asWETliWhkrq6GVHsix7b65nTc9T_u_cWFoo5r9iQIr0VPgnenyqGPP5khvihRq9Ze3MB9rff7zRCuVLCHw2MucEXInjxQ11cy7Ft5C5E1LeZoqnsgyPyM_1qfxYaWzKS9LH2XXPe8exawzHPflG3xHLanCfvLW9q6zMXfSQPvL2ox6NC1CeXdaThx451VI2usaM3_-YcMJrkauNKd2TJ0DKsQbp1fZRXrwmGyIN_Kv5XZiMAP1TmhmYkfYjJR4iEyXbsJwiDnaEHSbsOscOEKlnwtkvtgYgP5rOyX0jpMf7VT9mhX5fEDmDpw_8DzN3LRa5zr-f-MUfPVdcsTPnjZ9xgquSFacubmIz0bZhHJP0xrM_OFyEcT-aD64NB69zEUZDnsXDZMjB-wdjqd-xawiihxKfwJRmMvR1A43j6Ogyhr4OriSZAfM8dSe5mhyeQ7mLtbmb_TyvLf26hD8G-iXeGx-73vflxUqzSYpkuyYStnrOX2SKbLbPl5LyiNH0-ZmlRpPl8keSzxZyihBCSzhB7pmQx4SuUoDSZI_Q8e86S5fTISLZIyJGRJTomSQJmCSsJF1MhLuVU6dOEG1OzVYZestlEkJwJ42_1EJLsCv1DgBCYv070ytE85fXJgFkiuLHmxsVyK_x1YDO7zgcTlb8bc3Nxe8FHz4x-c9F5px4313h-q5-PnR99prg1KZNai9XZ2so4Ib7jOXF7rvMpVSVAe6dZ8_VUaeXmHdf0OnsMQHtv778CAAD__wB1I60">