【问题标题】:Is there a STL algorithm that finds last but that it also works on pointers?是否有一种 STL 算法可以找到最后但它也适用于指针?
【发布时间】:2020-09-16 21:05:50
【问题描述】:

我有无法切换到迭代器的现有代码。 如果可能的话,我仍然想使用 STL 来找到最后一项(或者如果你认为我们是从末尾迭代,那么首先)。 这可能吗?

std::find_end 除了是最糟糕的命名算法之外,使用起来似乎非常难看(我需要一个假的 1 元素序列和二进制谓词,相比之下忽略 1 个元素的值)。

我现在拥有的东西非常丑陋(特别是因为 bool* 的反向不是 bool* 所以我必须做丑陋的事情来获得 std::distance。

#include <algorithm>
#include <iostream>

int main()
{ 
    {
    bool arr[6] = {true,false,true,true,true,false};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
    // repeat test to make sure result is not an accident
    {
    bool arr[6] = {true,false,true,true,false,true};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
}

【问题讨论】:

  • 从 C++11 开始,std::begin(arr)std::end(arr) 给出了数组的开始和(过去)结束迭代器,可以传递给标准算法。 std::rbegin()std::rend() 给出了相应的反向迭代器。这些函数适用于数组,而不是指针。
  • Is there a STL algorithm ... but that it also works on pointers? 所有标准算法都使用指针。指针是迭代器。

标签: c++ stl


【解决方案1】:

在容器(包括 c 数组)中查找最后一个元素的索引的正确方法是使用 std::findreverse_iterators(对于双向容器),就像您尝试过的一样,但使用较少的 UB (&amp;arr[6]是 UB)。

using std::begin;
using std::rbegin;
using std::rend;

bool arr[6] = {...};
auto it = std::find(rbegin(arr), rend(arr), false);
if (it != rend(arr)) {
    auto idx = std::distance(begin(arr), it.base()) - 1;
    std::cout << "idx is " << idx << std::endl;
}

【讨论】:

  • 我不确定 &arr[6] 是 UB。
  • arr[6] 取消引用结束元素 UB,然后 &amp; 获取该元素的地址。 arr + 6 不是 UB,因为过去的结束元素没有被取消引用,只是指向。
  • 是的,它是 UB,感谢您的澄清,但它可能编译为相同的 asm:P
  • &amp;arr[6] 不是 UB。
【解决方案2】:

我不确定我是否得到了您需要的信息,但这段代码似乎可以正常工作:

int arr[6] = { 1, 2, 3, 4, 5 };
int pattern[1] = { 4 };
auto it = std::find_end(arr, arr + 5, pattern, pattern + 1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-18
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    相关资源
    最近更新 更多