生成从 0 到 n-1 的数字的惯用方法是什么?

What's the idiomatic way to generate the numbers from 0 to n-1?

本文关键字:方法 是什么 数字 n-1      更新时间:2023-10-16

在任意类型中以阵列或向量从0到n-1生成数字的可接受的C 成语是什么?

换句话说,我将如何写:

template <typename T> vector<T> generate_integers_upto(size_t n);

template <typename T> T* generate_integers_upto(size_t n);

惯用方式是按值返回。您可以使用std::iota来填充矢量以简单,但这是次要的:

#include <vector>
#include <numeric>
template<typename T>
std::vector<T> generate(std::size_t n)
{
  std::vector<T> v(n);
  std::iota(std::begin(v), std::end(v), T());
  return v;
}

只需按值返回,让编译器决定什么(RVO,MOVE返回等)更有效:

template<typename T>
std::vector<T> generate( std::size_t n , T begin = 0u )
{
    std::vector<T> result( n );
    std::iota( std::begin( result ) , std::end( result ) , begin );
    return result;
}

请注意,默认返回类型为unsigned int。当然,您可以将传递给函数的值更改以更改返回值,或明确指定返回类型:

int main()
{
    auto sequence = generate<float>( 100 );
}

此实现基于std::iota()标准库算法。

这取决于您想对这些数字做什么。

如果您真的想要一个范围,而不是容器,则boost::irange将足够。它甚至不需要任何[实质性的]内存!

它使您可以做这样的酷事:

#include <iostream>
#include <boost/range/irange.hpp>
using boost::irange;
using std::cout;
int main()
{
    for (auto i : irange(0, 42))
        cout << i << ' ';
}
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

如果要为您创建数组,请按值返回std::vector

如您的第一个示例,返回参考是无效的(如果向量是现在已经被销毁的局部变量)或怪异且容易出错(因为现在有一个需要以某种方式管理的矢量)。p>返回指针,大概是分配的数组,这是容易出错的,因为没有什么可以确保呼叫者正确地将其交易。

更灵活的替代方法是采用迭代范围。对于两对迭代器,将其重载超负荷可能是有意义的:

std::vector<int> v(10);       // non-empty vector
generate(v.begin(), v.end()); // replace existing elements

和一个迭代器和大小:

std::vector<int> v;             // empty vector
generate(back_inserter(v), 10); // insert new elements

请注意,C 11库具有std::iota,其作用类似于第一个版本(并且可以用于实现任何一个),但没有任何内容。