std::vector
几乎所有其他容器都有一种非常方便的边界检查方法:at()
. std::span
显然没有。
- 为什么?
- 有替代品吗?除了推出自己的
at()
?
std::vector
几乎所有其他容器都有一种非常方便的边界检查方法:at()
. std::span
显然没有。
at()
?相当笨重,但像这样:
template<class Container>
auto& at(Container&& c, std::size_t pos){
if(pos >= c.size())
throw std::out_of_range("out of bounds");
return c[pos];
}
template<class Iterator, class Container>
auto& at(Container&& c, Iterator&& it){
if(std::distance(c.begin(), it) >= c.size())
throw std::out_of_range("out of bounds");
return *it;
}
将 span 引入标准库的论文说:
范围检查和边界安全
对跨度封装的数据的所有访问在概念上都经过范围检查,以确保它们保持在跨度的范围内。由于在运行时未能满足 span 的 boundssafety 约束而实际发生的情况是未定义的行为。
也就是说,操作具有狭窄的合同,为实施者提供了自由。
如果您的标准库不允许您将行为控制到适当的粒度。gsl-lite提供了可配置的合同违规行为的替换。Microsoft GSL以前是可配置的,但现在总是在违反合同时终止,在此处讨论(这实际上可能是您想要的)。