如何解决在C ++中,如何检查指针是否在范围内?
直观地检查晶须指针p
位于[a
,b
)中
a<=p && p<b
但是,比较两个数组中的指针会导致未指定的行为,因此我们不能从此比较中安全地说出p
在[a
,b
)中。
有人可以肯定地检查这一点吗?
(如果可以为std::vector<T>::const_iterator
做,那会更好,但我认为这不可行。)
解决方法
如果我对您的理解正确,则需要检查向量迭代器是否在其他两个向量迭代器之间。
然后,您可以使用std::distance计算vector.begin与a,p和b之间的距离,然后简单比较从 distance 返回值获得的迭代器。
,这是部分解决方案。您可以利用比较会调用未指定行为的事实,以及core-constant-expression无法执行此操作的事实:
template<typename T>
constexpr bool check(T *p,T *a,T *b)
{
return a <= p and p < b;
}
现在可以像这样使用此功能:
int main()
{
int arr[5];
int arr_2[5];
constexpr bool b1 = check(arr + 1,arr,arr + 3); // ok
constexpr bool b2 = check(arr_2 + 1,arr + 3); // error
}
这里是demo。
这显然仅在编译时知道指针值的情况下有效。在运行时,没有进行此检查的有效方法。
,指针的解决方案是使用<functional>
中定义的比较对象,例如less
/ less_equal
等。
对于模板
greater
,less
,greater_equal
和less_equal
,任何指针类型的特殊化都会产生总顺序,即使内置运算符<
,>
,<=
,>=
不会。
所以指针的解决方案是:
template<typename T>
bool check(T *p,T *b)
{
return std::less_equal<T*>{}(a,p) && std::less<T*>{}(p,b);
}
这里是使用指针的working example。
对迭代器没有如此严格的保证;但是,这可以在c++20中解决,因为它提供了std::to_address
可以将可指向对象转换为指针。但是请注意,为比较目的执行此操作的行为仅对于连续的迭代器确实定义良好。
由于我们知道std::vector
迭代器覆盖了一个连续范围,因此我们可以使用它来检索基础指针(注意: 不对其取消引用,因为对于过去的指针将是未定义的行为。
因此对于std::vector<T>::iterator
,解决方案可能类似于:
template <typename T>
bool check(const std::vector<T>::const_iterator p,std;:vector<T>::const_iterator a,std::vector<T>::const_iterator b)
{
// Delegate to the pointer check version defined above,for brevity
return check(std::to_address(p),std::to_address(a),std::to_address(b));
}
这里是使用迭代器的working example。
1 相同的注释一直存在到c++11下的§23.14.7/2处,用类似的措词。
, C ++ 17的 std::distance(first,last)
可以同时使用,但是如果last
无法访问first
(例如,范围不同或无效的迭代器),则结果不确定。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。