`std::back()` 类似于 C++ 中的函数
`std::back()` like function in C++
我可以使用 std::begin()
和 std::end()
创建开始和结束迭代器。
例如:
int arr[4][4] = <something here>;
auto begin_it = std::begin(arr);
auto end_it = std::end(arr);
但是,为什么我们没有std::front()
和std::back()
。是否有任何具体原因需要省略它们?
有没有我可以使用的类似函数(当然除了 begin 和 end)?
并非所有容器都constant-time访问列表的最后一个元素。
例如std::forward_list
。
正如Marshall Clow所说,应该考虑跨容器访问时间不一致的问题。
我的观点是 front 会导致 UB 频繁出现在空的或未定义的 front 容器上,但 begin 不会导致这种情况,只要它没有被取消引用。
std::vector v;
auto item = std::front(v); // This line immediately cause undefined behavior.
如果std::front
存在,它带来的问题可能比它带来的便利更多。
因为 front
的每次调用都必须在 empty
之后。那就是两个函数调用方便..
std::vector v;
// ...
if( !v.empty() ){
auto item = std::front(v);
// ...tasks
}
嗯..方便吗?
而程序员可以通过 *begin(container)
有意识地得到 front
并在检查之前使用它。我们保存的只是一个 星号。
std::vector v;
// ...
if( !v.empty() ){
auto item = *std::begin(v);
// ...tasks
}
Is there any specific reason for them to be ommitted?
是否有任何具体原因包括?
东西不会因为可以被扔进标准库而被扔进标准库。标准库旨在包含 有用的 函数、模板等。 “举证责任”在于想要包含某些内容的人。只有在 use-case 已经建立,提交给标准委员会,并被所述委员会驳回之后,将某些东西称为“省略”才是准确的。
话虽如此,标准库中未包含某些内容的潜在原因有多种,“无用”只是其中之一。其他潜在原因包括“在所有平台上的实施都不够好”和“哦,我们没有想到这一点”。虽然我不知道哪个原因适用于此,但我可以通过将 std::end()
与假设的 std::back()
.
进行比较来提供一些思考依据
可以将 std::end()
与 C-style 数组(已知大小)或满足 "Container" 要求的任何内容一起使用,例如标准库中的所有容器。它在循环容器方面有很大的实用性,这是一种相当常见的操作。将 std::end()
添加到标准库的结果是标准库的许多算法不再需要模板特化来处理 C-style 数组。 (诚然,range-based for 循环具有类似的效果。)
可以将 std::back()
与 C-style 数组(已知大小)、std::array
或任何满足 "SequenceContainer" 要求的数组一起使用,例如作为字符串、向量、双端队列、列表和转发列表(标准库中没有其他内容)。它在……嗯……我正在画一个空白,但我承认 back()
有一般用途的可能性,尽管可能还差得远像循环一样普遍。
由于 std::back()
适用的情况少于 std::end()
,因此可能被忽略了。同时,由于 std::back()
适用的情况比 std::end()
少,因此它可能不符合包含在标准库中的“有用”标准。
Are there any similar functions I can use (apart from begin and end of course)?
您可以从 C-style 数组切换到 std::array
,然后使用 std::array::back()
。毕竟,std::array
只是一个 C-style 数组,包裹起来看起来像一个连续的序列容器。类型声明更长,但您正在寻找的功能变得随时可用。
标准库的目标是支持 C-style 数组,因为它是一个库,注定要被库作者做梦也想不到的代码使用。如果你不是在写一个库,你可能真的不需要支持 C-style 数组。
我可以使用 std::begin()
和 std::end()
创建开始和结束迭代器。
例如:
int arr[4][4] = <something here>;
auto begin_it = std::begin(arr);
auto end_it = std::end(arr);
但是,为什么我们没有std::front()
和std::back()
。是否有任何具体原因需要省略它们?
有没有我可以使用的类似函数(当然除了 begin 和 end)?
并非所有容器都constant-time访问列表的最后一个元素。
例如std::forward_list
。
正如Marshall Clow所说,应该考虑跨容器访问时间不一致的问题。
我的观点是 front 会导致 UB 频繁出现在空的或未定义的 front 容器上,但 begin 不会导致这种情况,只要它没有被取消引用。
std::vector v;
auto item = std::front(v); // This line immediately cause undefined behavior.
如果std::front
存在,它带来的问题可能比它带来的便利更多。
因为 front
的每次调用都必须在 empty
之后。那就是两个函数调用方便..
std::vector v;
// ...
if( !v.empty() ){
auto item = std::front(v);
// ...tasks
}
嗯..方便吗?
而程序员可以通过 *begin(container)
有意识地得到 front
并在检查之前使用它。我们保存的只是一个 星号。
std::vector v;
// ...
if( !v.empty() ){
auto item = *std::begin(v);
// ...tasks
}
Is there any specific reason for them to be ommitted?
是否有任何具体原因包括?
东西不会因为可以被扔进标准库而被扔进标准库。标准库旨在包含 有用的 函数、模板等。 “举证责任”在于想要包含某些内容的人。只有在 use-case 已经建立,提交给标准委员会,并被所述委员会驳回之后,将某些东西称为“省略”才是准确的。
话虽如此,标准库中未包含某些内容的潜在原因有多种,“无用”只是其中之一。其他潜在原因包括“在所有平台上的实施都不够好”和“哦,我们没有想到这一点”。虽然我不知道哪个原因适用于此,但我可以通过将 std::end()
与假设的 std::back()
.
可以将 std::end()
与 C-style 数组(已知大小)或满足 "Container" 要求的任何内容一起使用,例如标准库中的所有容器。它在循环容器方面有很大的实用性,这是一种相当常见的操作。将 std::end()
添加到标准库的结果是标准库的许多算法不再需要模板特化来处理 C-style 数组。 (诚然,range-based for 循环具有类似的效果。)
可以将 std::back()
与 C-style 数组(已知大小)、std::array
或任何满足 "SequenceContainer" 要求的数组一起使用,例如作为字符串、向量、双端队列、列表和转发列表(标准库中没有其他内容)。它在……嗯……我正在画一个空白,但我承认 back()
有一般用途的可能性,尽管可能还差得远像循环一样普遍。
由于 std::back()
适用的情况少于 std::end()
,因此可能被忽略了。同时,由于 std::back()
适用的情况比 std::end()
少,因此它可能不符合包含在标准库中的“有用”标准。
Are there any similar functions I can use (apart from begin and end of course)?
您可以从 C-style 数组切换到 std::array
,然后使用 std::array::back()
。毕竟,std::array
只是一个 C-style 数组,包裹起来看起来像一个连续的序列容器。类型声明更长,但您正在寻找的功能变得随时可用。
标准库的目标是支持 C-style 数组,因为它是一个库,注定要被库作者做梦也想不到的代码使用。如果你不是在写一个库,你可能真的不需要支持 C-style 数组。