return std::generate_n 的值迭代器,你能用它做什么?

return value iterator of std::generate_n, what can you do with it?

出于好奇!

std::generate_n 返回的 iterator 可以做什么?

Return 值 :

Iterator one past the last element assigned if count > 0, first otherwise.

    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto iterator = std::generate_n(std::back_inserter(v), 10, [&]() {return j++;});
    std::cout << "type: " << typeid(iterator).name() << '\n';
/*
    for (iterator = v.begin(); iterator< v.end(); iterator++){
        std::cout << *iterator << " " << endl;
    }
*/
    for(auto a : v)
        std::cout << a << " ";
    std::cout << std::endl;

输出:

type: St20back_insert_iteratorISt6vectorIiSaIiEEE
1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 

iterator显示了一些成员函数,但它们主要是运算符。


What can you do the returning iterator of std::generate_n?

您可以使用它向您的容器中插入元素。

鉴于std::generate_nreturns一个std::back_insert_iterator,定义在std::back_insert_iterator:

std::back_insert_iterator is a LegacyOutputIterator that appends to a container for which it was constructed. The container's push_back() member function is called whenever the iterator (whether dereferenced or not) is assigned to. Incrementing the std::back_insert_iterator is a no-op.

实际上,您的代码所做的是将 10 个 int 附加到 std::vector。我想 j 是用 0 初始化的,如果不是,您可能正在调用未定义的行为。


Return value:

Iterator one past the last element assigned if count > 0, first otherwise.

它总是指向应该插入新元素的最后一个元素之后,如果容器是空的,它将指向容器的第一个元素,这也是应该插入新元素的地方被插入。

示例:

iterator = 25;

会将 25 附加到矢量,您的输出将是:

 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 25

这是一个输出迭代器。您可以像使用任何输出迭代器一样使用它。它与您作为第一个参数传递的类型相同 - 甚至在没有生成任何内容的情况下也是相同的值。

后插入器并不是这个的理想示例,因为它并不真正关心位置(有趣的事实:增加后插入器没有任何作用)。一个更重要的用例是现有元素的迭代器,在这种情况下我们关心我们正在覆盖哪些元素。

扩展示例,对同一个容器使用两个不同的生成器:

auto generator1 = [&]() { return j++; };
auto generator2 = [&]() { return j--; };
auto it = v.begin();
it = std::generate_n(it, 5, generator1);
it = std::generate_n(it, 5, generator2);

假设你想为前半部分生成元素,然后为后半部分使用不同的生成器,那么你可以简单地写:

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    int j = 0;
    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto iterator = std::generate_n(v.begin(), 5, [&]() {return j++;});
    
    std::generate_n(iterator,5,[&](){ return j;});
    
    
    for (auto i : v){
        std::cout << i << " ";
    }
}

无需手动计算指向第一次调用后的元素的 iterator

输出为:

0 1 2 3 4 5 5 5 5 5 

在您的示例中,iterator 只是向量最后一个元素之后的迭代器,并没有带来太大的优势,因为它与 v.end().

相同