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.
4 Answers
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 :-)

- 166,810
- 27
- 341
- 521
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.

- 124,023
- 23
- 387
- 451

- 58,701
- 10
- 113
- 156
-
1I wouldn't buy the "have never heard someone talk about the 0st argument", because you normally don't even talk about the 0st element of an array. You say "1st", but its index is 0. However, the historic argument makes sense. Standard Library had `bind1st()` and `bind2nd()`, so a natural generalization to `n`-ary functions was "bind 3rd", "bind 4th", and so on. – Andy Prowl Mar 10 '13 at 21:11
-
1I've never heard "zero-st" but I _have_ heard "zero-th" ... that doesn't make it correct English though :) – Jonathan Wakely Mar 10 '13 at 21:13
-
@AndyProwl yes, that is not really convincing. Can you please edit it out? I'm on mobile and it is a pain. – pmr Mar 10 '13 at 21:14
-
1@pmr, as Andy says (and I say in my answer) it's still the _first_ item even in a zero-based list. But I have heard (and TBH said) "zeroth", partly in jest. – Jonathan Wakely Mar 10 '13 at 21:18
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.

- 35,360
- 15
- 114
- 174
-
While this is true, it could easily be made to work by giving `_0` the value 1, and `_1` the value 2, etc. so non-placeholders still had value 0. – Jonathan Wakely Oct 23 '16 at 12:46
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.

- 39,818
- 11
- 97
- 141

- 262,606
- 27
- 330
- 524
-
Upvoted since I'm guessing plenty of people never made it to the last line of your answer... I was actually thinking something similar but serious though, regarding POSIX shells (`$0`, `$1`, etc) – Mark K Cowan Jul 14 '15 at 09:10