繁体   English   中英

忽略大小模板的 std::array::iterator

[英]std::array::iterator that ignores the size template

我正在实现一个 function,它想要遍历 std::array 中的多个元素,但我并不关心 std::array 有多长。 所以我在想下面的function:

#include <stdio.h>
#include <array>
#include <iterator>

void foo(std::array<bool,0>::const_iterator begin, std::array<bool,0>::const_iterator end)
{
    printf("iterator");
}

int main()
{
    std::array<bool, 25> one;
    std::array<bool, 33> two;

    foo(one.cbegin(), one.cend());
    foo(two.cbegin(), two.cend());
}

我对此很满意,除了std::array<bool,0> 我的问题是,是否有另一种方法来指定此 function 所需的迭代器?


更新

有些事情我应该提一下。 当然,这段代码是更大的 scope 的一部分,我试图尽可能多地隐藏细节。

  1. 我想确保正在使用的迭代器是bool的。
  2. 我正在使用 C++14
  3. function 是 class 接口的一部分,我希望能够处理多种阵列大小。 我不想打扰接口的实现者确切地知道数组的大小。
class MyInterface
{
public:
    virtual foo(std::array<bool,0>::const_iterator begin, std::array<bool,0>::const_iterator end) = 0;

    ~MyInterface() = default;
};

我记得虚函数不能被模板化。 这意味着我将不得不对我的整个界面进行模板化,而这将完全失去我最初尝试这个的原因。

您可以将其作为 function 模板

template <typename I>
void foo(I begin, I end)
{
    std::cout << "iterator";
}

您不需要关心容器类型(和大小),您可以传递std::arraystd::vectorstd::string等迭代器,甚至是原始指针(这也满足迭代器的要求)。

只需使用span

#include <array>
#include <span>

class MyInterface {
public:
    virtual void foo(std::span<bool> barr) = 0;

    // interface destructors should be virtual
    virtual ~MyInterface() = default;
};

void bar(MyInterface& interface) {
    std::array<bool, 42> arr;
    interface.foo(arr);
}

如果您无法访问 C++20 编译器,则可以使用 gsl 中的gsl gsl::span代替。

使用模板:

template <size_t N>
void foo(std::array<bool,N>::const_iterator begin, std::array<bool,N>::const_iterator end)
{
    printf("iterator");
}

现在只要两个迭代器都来自一个大小为N的数组,这个 function 就可以工作。


如果您想接受来自不同大小的 arrays 的迭代器,您只需为第二个迭代器添加另一个模板参数,例如

template <size_t N, size_t M>
void foo(std::array<bool,N>::const_iterator begin, std::array<bool,M>::const_iterator end)
{
    printf("iterator");
}

如果 function 在引用 std::array 是多余的时接受两个迭代器。 只需像这样声明 function

template <class Iterator>
void foo( Iterator first, Iterator last );

在声明中,您可以命名与 function 中使用的迭代器类型对应的迭代器,例如

template <class ForwardIterator>
void foo( ForwardIterator first, ForwardIterator last );

或者代替名称ForwardIterator ,您可以使用名称BidirectionalIteratorRandomAccessIterator进行自我记录。

如果您需要知道迭代器的值类型,您可以使用不同的方法。 例如

template <class Iterator>
void foo( Iterator first, Iterator last )
{
    using value_type = typename std::iterator_traits<Iterator>::value_type;
    if ( first != last )
    {
         value_type item1 = *first;
         // or
         auto item2 = *first;
         //
         const auto &item3 = *first;
         //...             
    }
}

在这种情况下,您将有一个灵活的 function 定义。 例如,如果将来您将std::array<N, bool>更改为std::vector<bool> function 将照常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM