This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
std::bind vs ::bind ambiguity
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 31 Mar 2011 20:55:27 +0100
- Subject: std::bind vs ::bind ambiguity
.While recompiling an application using C++0x I got an error from the
code below, which is well-formed in C++03:
#include <functional>
#include <sys/types.h>
#include <sys/socket.h> // declares bind()
using namespace std;
int b(int fd, sockaddr* sa, socklen_t len)
{
return bind(fd, sa, len);
}
error: cannot convert _Bind_helper<int&, sockaddr*, socklen_t>:: type to int
The problem is that the socket bind() function has this signature:
int bind(int, const sockaddr*, socklen_t);
so the call in the example using a non-const pointer finds that the
variadic template std::bind is a better match. The same would happen
if the third argument was any integral type except socklen_t.
Although I think the C++0x standard requires that behaviour, it's not
at all helpful, because attempting to invoke the returned bind
expression would be ill-formed, because int is not a callable type.
I think it would be better to constrain std::bind so that it doesn't
take part in overload resolution if the Functor parameter is an
integer type e.g.
template<typename _Functor, typename... _ArgTypes>
inline
typename enable_if<
!is_integral<typename decay<_Functor>::type>::value,
typename _Bind_helper<_Functor, _ArgTypes...>::type>::type
bind(_Functor&& __f, _ArgTypes&&... __args)
Any objections?
No change is needed for the other std::bind overload, because it can
only be called with an explicit template argument list, so there is no
way for calls to the (non-template) socket ::bind() function to
resolve to bind<R>.