c++ 中的大多数内容都是 0,而不是基于 1。只是出于好奇,为什么占位符 1 基于?意思是 _1 是第一个参数,而不是 _0。
4 回答
因为它就是这样boost::bind
做的,Boost.Bind 作者编写了将其添加到 TR1 的提案,并被复制到标准中。
至于为什么 Boost.Bind 这样做,我不知道,但我会冒险猜测它可能std::bind1st
与std::bind2nd
来自 STL 的 1998 年标准相匹配。在那种情况下,“第一个”即“第一个”是正确的(即使在从零开始的索引系统中,索引零处的项目也是第一个,而不是第零个项目。)
所以也许占位符应该是_1st
, _2nd
,等_3rd
,_4th
但对于不知道序数不一致后缀的非英语使用者来说,它可能更容易记住_1
等_2
。
不过只是一个疯狂的猜测。我从来没有想过这个问题,所以现在我也很好奇:-)
该约定可能是从前身 Boost.bind 继承而来的。
至于为什么 Boost 库选择从 1 开始:作为 C++03 一部分的绑定器使用 first_argument 和 second_argument 作为类型名称。
C++ 标准库具有bind1st()
and 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 绑定库的设计者是 MSDOS 批处理语法的粉丝。
在批处理语法中,%1
指的是第一个参数、%2
第二个、%3
第三个等。但由于%
不是有效的 C++ 标识符,他们将其替换为_
.
在 MSDOS 批处理语法中,%0
是指批处理文件的名称。在这种情况下,_0
将绑定到您调用的函数_1
,_2
等_3
。
实际上,不,不是。