简体   繁体   English

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

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

What's the acceptable C++ idiom for generating the numbers from 0 to n-1, in an arbitrary type, in an array or a vector? 在数组或向量中以任意类型生成从0到n-1的数字的可接受的C ++惯用法是什么?

In other words, how would I write: 换句话说,我该怎么写:

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

or 要么

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

The idiomatic way would be to return by value. 惯用的方法是按值返回。 You could use std::iota to fill the vector for simplicity, but this is secondary: 为了简单起见,您可以使用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;
}

Just return by value and let the compiler decide what (RVO, move return, etc) is more efficient: 只需按值返回,然后让编译器决定哪种方法(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;
}

Note that the default return type is unsigned int . 请注意,默认返回类型为unsigned int Of course you could change the value passed to the function to change the return value, or specify explicitly the return type: 当然,您可以更改传递给函数的值以更改返回值,或显式指定返回类型:

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

This implementation is based on the std::iota() standard library algorithm. 此实现基于std::iota()标准库算法。

It rather depends on what you want to do with those numbers. 而是取决于您要如何处理这些数字。

If you really want a range, not a container, then boost::irange will more than suffice. 如果您真的想要一个范围,而不是一个容器,那么boost::irange就足够了。 It doesn't even need any [substantial] memory! 它甚至不需要任何[大量]内存!

It lets you do cool stuff like this : 可以让您做一些很酷的事情

#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

If you want the function to create the array for you, then return std::vector by value. 如果要让函数为您创建数组,请按值返回std::vector

Returning a reference, as your first example does, is either invalid (if the vector was a local variable that's now been destroyed) or weird and error-prone (since there's now a vector somewhere that needs managing somehow). 如您的第一个示例所示,返回引用要么无效(如果向量是现在已销毁的局部变量),要么是奇怪且容易出错的(因为现在某个地方需要某种方式管理向量)。

Returning a pointer, presumably to an allocated array, is error-prone since there's nothing to make sure the caller deallocates it correctly. 返回指针(大概是分配的数组)很容易出错,因为没有任何东西可以确保调用者正确地分配它。

A more flexible alternative is to take an iterator range. 更为灵活的替代方法是采用迭代器范围。 It might make sense to overload it for both a pair of iterators: 对于两个迭代器都可以重载它:

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

and an iterator and a size: 以及迭代器和大小:

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

Note that the C++11 library has a std::iota which acts like the first version (and can be used to implement any of these), but nothing like the second. 请注意,C ++ 11库具有一个std::iota ,其行为类似于第一个版本(可用于实现其中任何一个),但与第二个版本完全不同。

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

相关问题 在间隔[0,n-1]中生成k个唯一随机数? - Generate k unique random numbers in the interval [0,n-1]? 更准确的平均方法是ARR [0] / N + ARR [1] / N…+ ARR [N-1] / N或(ARR [0] + ARR [1]…+ ARR [N-1] )/ N是否为两倍? - What is more accurate way to average, ARR[0]/N+ARR[1]/N…+ARR[N-1]/N or (ARR[0]+ARR[1]…+ARR[N-1])/N in double? C++ 从 0:n-1 (n &gt; k) 范围内随机抽取 k 个数字而不进行替换 - C++ randomly sample k numbers from range 0:n-1 (n > k) without replacement (n&(n-1))== 0和n&(n-1)== 0在C ++中做什么? - What do (n&(n-1))==0 and n&(n-1)==0 do in C++? while(n--)和while(n = n-1)之间有什么区别? - what is the difference between while(n--) and while(n=n-1)? 什么是通过后退到任何插入器来获得向后插入器的惯用方法? - What's the idiomatic way to get a backwards inserter with a fallback to any inserter? 遍历boost :: mpl :: list的惯用方式是什么? - What's the idiomatic way to traverse a boost::mpl::list? 使用ifstream解析文本的惯用方式是什么? - What's the idiomatic way of parsing text by using ifstream? 在**网格中计算从(0,0)到(n-1,n-1)的总路径 - Counting total Paths from (0,0) to (n-1,n-1) in a n*n grid 排序这些n ^ 2数字的最快方法是什么? - What is the fastest way to sort these n^2 numbers?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM