[英]What's the idiomatic way to generate the numbers from 0 to n-1?
在数组或向量中以任意类型生成从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,移动返回等)更有效:
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
。
如您的第一个示例所示,返回引用要么无效(如果向量是现在已销毁的局部变量),要么是奇怪且容易出错的(因为现在某个地方需要某种方式管理向量)。
返回指针(大概是分配的数组)很容易出错,因为没有任何东西可以确保调用者正确地分配它。
更为灵活的替代方法是采用迭代器范围。 对于两个迭代器都可以重载它:
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
,其行为类似于第一个版本(可用于实现其中任何一个),但与第二个版本完全不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.