【问题标题】:`std::back()` like function in C++`std::back()` 类似于 C++ 中的函数
【发布时间】:2020-08-26 03:07:55
【问题描述】:

我可以使用 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/size(或它们所替代的替代品)。
  • 不确定省略它们的原因,可能只是没有理由包含这些功能。如果你出于某种原因想要它们,你可以自己写
  • 我的观点是front 会经常在空的或未定义的前端容器上导致 UB,但只要不取消引用 begin 就不会导致这种情况。
  • @LouisGo,但他们本可以验证的,不是吗?

标签: c++ containers libstdc++


【解决方案1】:

并非所有容器都可以对列表的最后一个元素进行恒定时间访问。

例如std::forward_list

【讨论】:

    【解决方案2】:

    就像 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
    }
    

    HMM.. 方便吗? 而程序员可以通过*begin(container) 有意识地获取front 并在检查前使用它。我们保存的只是一个星号

    std::vector v;
    // ...
    if( !v.empty() ){
        auto item = *std::begin(v); 
        // ...tasks
    }
    

    【讨论】:

    【解决方案3】:

    有什么具体的理由可以省略吗?

    是否有任何具体原因包含

    事物不会仅仅因为它们可以被扔进标准库。标准库旨在由有用 函数、模板等组成。 “举证责任”在于想要包含某些内容的人。只有在用例建立、提交给标准委员会并被该委员会驳回之后,才能准确地将其称为“省略”。

    话虽如此,标准库中未包含某些内容的潜在原因有多种,“无用”只是其中之一。其他潜在原因包括“在所有平台上的实施都不够好”和“哦,我们没想到”。虽然我不知道这里适用的原因是什么,但我可以通过将 std::end() 与假设的 std::back() 进行比较来提供一些思考。

    可以将std::end() 与C 样式数组(已知大小)或任何满足"Container" 要求的对象一起使用,例如标准库中的所有容器。它在循环容器方面非常有用,这是一种相当常见的操作。将std::end() 添加到标准库的结果是标准库的许多算法不再需要模板特化来处理C 样式数组。 (诚​​然,基于范围的 for 循环也有类似的效果。)

    可以将std::back() 与C 样式数组(已知大小)、std::array 或任何满足"SequenceContainer" 要求的对象一起使用,例如字符串、向量、双端队列、列表和转发列表(标准库中没有其他内容)。它在……嗯……我在画一个空白,但我会同意back() 的一般用途的可能性,尽管可能远没有像循环。

    由于std::back() 适用于比std::end() 更少的情况,它可能被忽略了。同时,由于std::back() 适用的情况比std::end() 少,它可能不符合包含在标准库中的“有用”标准。

    我可以使用任何类似的功能吗(当然除了开始和结束)?

    您可以从 C 样式数组切换到 std::array,然后使用 std::array::back()。毕竟,std::array 只是一个 C 风格的数组,被包装起来看起来像一个连续的序列容器。类型声明更长,但您正在寻找的功能变得随时可用。

    标准库的目标是支持 C 风格的数组,因为它是一个库,注定要被库的作者从未梦想过的代码使用。如果您不编写库,则可能不需要支持 C 样式的数组。

    【讨论】:

      猜你喜欢
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多