Boost logo

Boost :

Subject: [boost] [bind] Function call operator is a template?!
From: Andy Venikov (avenikov_at_[hidden])
Date: 2009-12-16 17:38:06

All this time I've been using bind quite happily without really going
into the details of its implementation.
Recently, however, I had to discover the hard way that the function call
operator that is produced as part of the bind() return is a template!

I guess most of the time one would not care if it's a template or not as
long as you can call the resulting functor with the right signature.

It does, however, make a difference. The difference can be seen when
calling the resulting functor with wrong arguments. The error detection
happens earlier in the case when functor's operator() is a concrete
function as opposed to a template. And that plays bad tricks with SFINAE.

You see, recently I was faced with a challenge where I had to check at
compile time whether calling a template argument with a specific
signature is a well-formed expression. Something similar to Eric
Niebler's "can_be_called<>":

Well, this technique won't work with bind(), because the template member
operator() will happily accept ANY argument during SFINAE and the error
detection will happen much later, when you actually try to call the functor.

I'm not going to debate whether it's right or wrong, but I'm still
curious - why did it have to be a template? When bind() is called it
already has all the information about the function's signature so it
could construct a concrete member operator() without resorting to
templates. For example bind(main) could easily determine that the
signature is <int (int, char * [])> and could create a functor with a
single "int operator()(int, char *[])", instead of a template. It's not
like it's lambdas, where when you say _1 + _2 you literally mean
parameters of any type.


Boost list run by bdawes at, gregod at, cpdaniel at, john at