Question

Most everything in c++ is 0, not 1 based. Just out of curiosity, why are placeholders 1 based? Meaning _1 is the first parameter, not _0.

Was it helpful?

Solution

Because that's how boost::bind does it, and the Boost.Bind author wrote the proposal to add it to TR1 and that got copied into the standard.

As for why Boost.Bind does it that way, I don't know, but I would hazard a guess it might be to match std::bind1st and std::bind2nd from the 1998 standard, which came from the STL. In that context "1st" i.e. "first" is correct (even in a zero-based indexing system the item at index zero is the first, not the zeroth, item.)

So maybe the placeholders should be _1st, _2nd, _3rd, _4th etc. but for non-English speakers who don't know the inconsistent suffixes on ordinal numbers it's probably easier to remember _1, _2 etc.

Just a wild guess though. The question had never occurred to me so now I'm curious too :-)

OTHER TIPS

The convention was probably carried over from the predecessor Boost.bind.

As to why the Boost library chose starting with 1: the binders that have been part of C++03 used first_argument and second_argument as type names.

The C++ Standard Library had bind1st() and bind2nd(), so a natural generalization to n-ary functions was "bind 3rd", "bind 4th", and so on.

Neither of those is a real reason, but offer a likely explanation.

An advantage to this is workings of std::is_placeholder. The result isn't just true or false, it's the value of the placeholder itself.

std::is_placeholder<_1>::value == 1
std::is_placeholder<_2>::value == 2
std::is_placeholder<_7>::value == 7

but anything not a placeholder will evaluate to 0 (which is of course, false). If placeholders started at _0 this wouldn't work.

The designers of boost bind library were fans of MSDOS batch syntax.

In batch syntax, %1 refers to the first argument, %2 the second, %3 the third, etc. But because % is not a valid C++ identifier, they replaced it with a _.

In MSDOS batch syntax, %0 refers to the name of the batch file. In this case, _0 would be bound to the function that you call _1, _2, _3 etc on.

Actually, no, not really.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top