This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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>.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]