我将翻译如下内容:
如果存在一个整数n,满足条件
否则,如果存在一个整数n,满足条件
否则,返回
明显的实现方式如下:
我希望实现一个函数,用于确定给定指针是否指向给定缓冲区。规范如下:
template <typename T>
bool points_into_buffer (T *p, T *buf, std::size_t len);
如果存在一个整数n,满足条件
0 <= n && n < len
,并且p == buf + n
,则返回true
。否则,如果存在一个整数n,满足条件
0 <= n && n < len * sizeof(T)
,并且reinterpret_cast<char *>(p) == reinterpret_cast<char *>(buf) + n
,则行为未定义。否则,返回
false
。明显的实现方式如下:
template <typename T>
bool points_into_buffer (T *p, T *buf, std::size_t len) {
return p >= buf && p < buf + len;
}
但这在标准C++中是未定义行为:关系比较指针仅对指向同一数组的指针进行定义。
另一种选择是使用标准库的比较器对象:
template <typename T>
bool points_into_buffer (T *p, T *buf, std::size_t len) {
return std::greater_equal<T *>()(p, buf) && std::less<T *>()(p, buf + len);
}
这个函数保证在我需要它返回 true
的时候返回 true
,避免了未定义的行为,但是可能会有误报:对于给定的 int a; int b;
,它允许 points_into_buffer(&a, &b, 1)
返回 true
。
它可以通过循环实现:
template <typename T>
bool points_into_buffer (T *p, T *buf, std::size_t len) {
for (std::size_t i = 0; i != len; i++)
if (p == buf + i)
return true;
return false;
}
然而,编译器很难优化掉这个循环。
有没有一种有效的方法来编写这个代码,在当前的编译器和启用了优化的情况下,结果可以在常数时间内确定?
greater
、less
、greater_equal
和less_equal
,即使内置的运算符<
、>
、<=
、>=
不成立,任何指针类型的特化都会产生一个全序。" - user743382p < q
的结果被定义时,std::less<T *>()(p, q)
必须给出相同的结果,其他运算符也是如此。) - user743382