The highest placeholder index in a lambda expression determines the arity of the resulting function object. However, this is just the minimal arity, as the function object can take arbitrarily many arguments; those not needed are discarded. Consider the two bind expressions and their invocations below:
bind(g, _3, _3, _3)(x, y, z); bind(g, _1, _1, _1)(x, y, z);This first line discards arguments x and y, and makes the call:
g(z, z, z)whereas the second line discards arguments y and z, and calls:
g(x, x, x)In earlier versions of the library, the latter line resulted in a compile time error. This is basically a tradeoff between safety and flexibility, and the issue was extensively discussed during the Boost review period of the library. The main points for the strict arity checking was that it might catch a programming error at an earlier time and that a lambda expression that explicitly discards its arguments is easy to write:
(_3, bind(g, _1, _1, _1))(x, y, z);This lambda expression takes three arguments. The left-hand argument of the comma operator does nothing, and as comma returns the result of evaluating the right-hand argument we end up with the call g(x, x, x) even with the strict arity.
The main points against the strict arity checking were that the need to discard arguments is commonplace, and should therefore be straightforward, and that strict arity checking does not really buy that much more safety, particularly as it is not symmetric. For example, if the programmer wanted to write the expression _1 + _2 but mistakenly wrote _1 + 2, with strict arity checking, the complier would spot the error. However, if the erroneous expression was 1 + _2 instead, the error would go unnoticed. Furthermore, weak arity checking simplifies the implementation a bit. Following the recommendation of the Boost review, strict arity checking was dropped.