Большинство всего в c ++ основано на 0, а не на 1. Просто из любопытства, почему заполнители 1 основаны? Значение _1 является первым параметром, а не _0.
Потому что вот как boost::bind
делает это, и автор Boost.Bind написал предложение добавить его в TR1, и это было скопировано в стандарт.
Что касается того, почему Boost.Bind делает это таким образом, я не знаю, но я рискнул бы предположить, что это может соответствовать std::bind1st
а также std::bind2nd
от стандарта 1998 года, который пришел из STL. В этом контексте «1-й», т. Е. «Первый», является правильным (даже в системе индексации на основе нуля элемент с нулевым индексом является первый, не нулевое, вещь.)
Так что, возможно, заполнители должны быть _1st
, _2nd
, _3rd
, _4th
и т.д., но для не говорящих по-английски, которые не знают противоречивые суффиксы на порядковые номера это, вероятно, легче запомнить _1
, _2
и т.п.
Просто дикая догадка, хотя. Вопрос никогда не приходил мне в голову, так что теперь мне тоже любопытно 🙂
Соглашение, вероятно, было перенесено из предшественника Boost.bind.
Относительно того, почему библиотека Boost выбрала, начиная с 1: связыватели, которые были частью C ++ 03, использовали first_argument и second_argument в качестве имен типов.
Стандартная библиотека C ++ имела bind1st()
а также bind2nd()
Таким образом, естественным обобщением для n-арных функций было «bind 3rd», «bind 4th» и так далее.
Ни одна из них не является реальной причиной, но предлагает вероятное объяснение.
Преимуществом этого является работа std::is_placeholder
, Результат не просто истина или ложь, это ценность самого заполнителя.
std::is_placeholder<_1>::value == 1
std::is_placeholder<_2>::value == 2
std::is_placeholder<_7>::value == 7
но все, что не заполнитель будет оценивать 0
(что, конечно, ложно). Если заполнители начались в _0
это не сработает.
Разработчики библиотеки Boost Bind были поклонниками пакетного синтаксиса MSDOS.
В пакетном синтаксисе, %1
относится к первому аргументу, %2
второй, %3
третий и т. д. Но потому что %
не является допустимым идентификатором C ++, они заменили его на _
,
В пакетном синтаксисе MSDOS %0
ссылается на имя командного файла. В этом случае, _0
будет привязан к функции, которую вы вызываете _1
, _2
, _3
и т. д.
На самом деле нет, не совсем.