On Dec 24, 3:04 pm, Howard Hinnant <
howard.hinn...@gmail.com> wrote:
> I could be wrong here, bind is quite a complex machine, but I don't
> think this is going to work for any known bind implementation. Nor do
> I believe the committee intended that it work.
I was thinking that maybe I could implement this, if I were just
clever enough. But I'm beginning to think it is unimplementable.
Consider this case:
#include <functional>
#include <cassert>
using namespace std;
using namespace std::placeholders;
long long
g(char a, int b, unsigned c)
{
return a + b + c;
}
int main()
{
auto p = bind(g, _2, _2, _2);
assert(p() == 9); // #1
assert(p(5.5) == 9); // #2
assert(p(5.5, 3ull) == 9); // #3
assert(p(5.5, 3ull, 'a') == 9); // #4
assert(p(5.5, 3ull, 'a', 6u) == 9); // #5
}
#1 and #2 do not compile. So let's not worry about those. But this
implies that that decltype(p) is not a unary_function, and thus
doesn't have an argument_type type.
#3 compiles. It is a binary_function. What is first_argument_type?
It could be anything! It is completely ignored. char is no more
appropriate than int, which is no more appropriate than class X! (you
can read that as an exclamation point or a factorial operator :-)).
second_argument_type must be convertible to all of char, int and
unsigned. But which, if any, of those three types should
second_argument_type be?
#4 and #5 also compile and work correctly. But they aren't unary or
binary functors, and yet the decltype(p) is the same type.
*Maybe* a sufficiently smart bind could not define first_argument_type
in this case, or maybe set it to void. And *maybe* it could set
second_argument_type to common_type<char, int, unsigned>::type. But
would this actually be useful? The rules get so complicated that it
becomes difficult for clients to have an obvious and expected outcome
of bind.
*Maybe* the design of argument_type, first_argument_type,
second_argument_type, not1 and not2 are simply obsolete with respect
to bind. boost::bind has moved beyond these needs/ideas for years
now.
Howard