From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2005-08-08 02:54:05


Hi all,

As part of the asio library I have been using named placeholders for
the common arguments to callback functions. For example:

  asio::async_send_n(sock, buffer, length,
    boost::bind(mycallback, asio::arg::error,
      asio::arg::last_bytes_sent, asio::arg::total_bytes_sent));

rather than:

  asio::async_send_n(sock, buffer, length,
    boost::bind(mycallback, _1, _2, _3));

I find having named placeholders saves time and helps prevent errors to
do with the ordering of the parameters (e.g. in the case of something
like the last_bytes_sent/total_bytes_sent example where both are
size_t, and so incorrect order will not be detected by the compiler).

Unfortunately, from my reading of the TR1 bind doco at

  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1455.htm

it simply defines the placeholders as:

  namespace std {
    namespace placeholders {
      extern unspecified _1;
      extern unspecified _2;
      extern unspecified _3;
      // implementation defined number of additional placeholders
    }
  }

and it doesn't say anything about the type of the placeholders. Since
the placeholders are CopyConstructible, it seems like I ought to be
able to do something using a typedef (if there was one), e.g:

  std::placeholders::_1_t my_placeholder(std::placeholders::_1);

Is there some TR1-compatible (and therefore portable) way of working
around it that's eluding me (other than #define :). It seems a shame
not to have such a feature, especially if over time more libraries use
complex function objects in their interfaces.

Cheers,
Chris