std :: initializer_list和std :: span有什么区别?两者都是某种类型的值的连续序列。两者都不是所有者。那么我们什么时候使用第一个,什么时候使用后者?
简短的答案是std::initializer_list<T>
用于初始化的目的是创建新范围。虽然std::span<T>
用于指代现有范围,但可提供更好的API。
std::initializer_list<T>
是一种语言功能,实际上构造了一个新数组并拥有它。它解决了如何方便地初始化容器的问题:
template <typename T>
struct vector {
vector(std::initializer_list<T>);
};
vector<int> v = {1, 2, 3, 4};
这会std::initializer_list<int>
即时创建一个包含四个整数的动态对象,并将其传递给它,vector
以便可以正确地构造自己。
实际上,这是唯一std::initializer_list<T>
应该使用的地方:为方便起见,构造函数或函数参数都会动态传递范围(单元测试是需要这种便利的常见位置)。
std::span<T>
另一方面,用于指代现有范围。它的工作是替换以下形式的功能:
void do_something(int*, size_t);
与
void do_something(std::span<int>);
这使得此类功能通常更易于使用且更安全。std::span
可以在任何适当的连续范围内构造,因此以前面的示例为例:
std::vector<int> v = {1, 2, 3, 4};
do_something(v); // ok
它也可以用来替换以下形式的函数:
void do_something_else(std::vector<unsigned char> const&);
具体来说,只能使用a来调用vector
:
void do_something_else(std::span<unsigned char const>);
可以使用上的任何支持连续存储来调用unsigned char
。
随着span
你必须要小心,因为它基本上是一个引用,只是没有得到与拼写&
,但它是一个非常有用的类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句