现代C++核心指导中提到的 span<T> 类型到底是哪个?
来源:网络整理 网络用户发布,如有版权联系网管删除 2018-09-04
span<T>就是在CppCon 2015里面提到的array_view<T>的新名称,它的主要作用有两个:
- 解决传参时数组退化所导致的丢失数组尺寸的问题
- 更容易地检查出因为范围(ranges)大小错误而产生的问题
举几个例子:
1. 给定一个int数组,如何设计一个函数为数组的所有元素+1?
(来自C++ Core Guidelines 条款P.7)
void increment1(int* p, int n) // 容易出错
{
for (int i = 0; i < n; ++i)
++p[i];
}
void use1(int m)
{
const int n = 10;
int a[n] = {};
// ...
increment1(a, m); // 不慎将 n 错打为 m,或者设计者希望 m <= n
// 如果在 m > n 的情况下调用increment1呢?
// ...
}
这种情况下就可以使用span<int>:
void increment2(span<int> p) // 改用span
{
for (int& x : p)
++x;
}
void use2(int m)
{
const int n = 10;
int a[n] = {};
// ...
increment2({a, m}); // 不慎将 n 错打为 m,或者设计者希望 m <= n
// ...
}
而且如果设计者希望increment作用于所有元素,可以这样:
void use3(int m)
{
const int n = 10;
int a[n] = {};
// ...
increment2(a); // 无须指出元素个数
// ...
}
2. 如何将一个数组里面的若干个元素复制到另一个数组里?
(来自C++ Core Guidelines 条款I.13)
你可能会这样做:
template <typename T>
void copy_n(const T* p, T* q, int n); // 从 p 里复制 n 个元素到 q
- 如果 q 的元素个数比 n 小呢?这样有部分无关内存会被重写。
- 如果 p 的元素个数比 n 小呢?这样有部分无关内存会被读取。
这时就可以使用span:
template <typename T>
void copy(span<const T> p, span<T> r); // 复制 p 的所有元素到 q
3. 有一个Circle数组,如何使用一个draw函数打印所有的Circle对象?
(来自C++ Core Guidelines 条款I.13)
class Shape { /* ... */ };
class Circle : public Shape { /* ... */ }
void draw(Shape* p, int n); // 参数是 Shape* 而不是 Circle*
Circle arr[10];
// ...
draw(arr, 10); // 调用了参数为Shape* 的函数,可能不是调用者的本意
- 无法确定 n 是否应该是 p 的大小。(虽然有很大可能,但函数声明无法保证这一点)
- Circle[10] 先被隐式地转换成了 Circle* ,又被转换成了 Shape* ,没有任何警告。
void draw2(span<Circle>);
Circle arr[10];
// ...
draw2(span<Circle>(arr)); // 自动推导元素个数
draw2(arr); // 自动推导元素类型与个数
void draw3(span<Shape>);
draw3(arr); // 错误:无法将 Circle[10] 转换为 span<Shape>
4. 如何从任意一段区间(元素类型为X)搜索某个X类特定值?
(来自C++ Core Guidelines 条款F.24)
X* find(span<X> r, const X& v); // 从 r 里搜寻 v
vector<X> vec;
// ...
auto p = find({vec.begin(), vec.end()}, X{}); // 在vec里搜寻值为 X{} 的元素
-------------------------------------------------------------------------------------------------
最后放上微软的span实现:GSL/span.h at master Microsoft/GSL GitHub
查看评论 回复
"现代C++核心指导中提到的 span<T> 类型到底是哪个?"的相关文章
- 上一篇:各种C++编译器的性能对比
- 下一篇:武汉C_C++软件开发_教育联展网