是否合法,检查的子对象的地址是否在包含对象的范围
2个问题中:是否合法,检查的子对象的地址是否在包含对象的范围
是有定义的行为也形成了如下的代码?
是否有任何可能的C++实现的,它可以断言?
码(C++ 11和更高):
#include <cassert> #include <utility>
#include <ciso646>
template<class T>
auto to_address(T* p) { return reinterpret_cast<unsigned char const*>(p); }
/// Test whether part is a sub-object of object
template<class Object, class Part>
bool is_within_object(Object& object, Part& part)
{
auto first = to_address(std::addressof(object)),
last = first + sizeof(Object);
auto p = to_address(std::addressof(part));
return (first <= p) and (p < last);
}
struct X
{
int a = 0;
int& get_a() { return a; }
int& get_b() { return b; }
private:
int b = 0;
};
int main()
{
X x;
assert(is_within_object(x, x.get_a()));
assert(is_within_object(x, x.get_b()));
}
注意a
和b
具有不同的访问说明。
回答:
指针比较在[expr.rel]/3-4定义:
比较不等对象指针被定义为如下:
- 如果两个指针指向相同的阵列的不同元件,或者子对象物,指向具有较高下标的元素的指针比较大。
- 如果两个指针指向同一对象的不同的非静态数据成员,或这些成员的子对象,递归地,指针到后来宣称构件比较大提供的两个成员都具有相同的访问控制和提供它们的类不是一个工会。
- 否则,既不指针比较大于另一个。
如果两个操作数p和q比较相等,则p= q且p> = q都产生真并且pq都产生假。否则,如果指针p比指针q进行比较时,P> = Q,P> Q,Q < = p和q = p和q> P均产生错误。否则,每个操作员的结果都是未指定的。
,我们可以从中得出什么结论?
有一个对象内的相同类型的指针的总订单,但没有指针指向不同的对象或不同的访问控制的不同子对象的顺序。这种缺乏指针的一般总订单使得is_within_object()
意义不大。在你期望它返回true
的情况下,它可以工作。在你期望它返回false
的情况下,这些操作符的结果是不确定的?这不是一个非常有用的结果。
也就是说说,我们对此有一个巨大的漏洞在[comparisons]形式:
对于模板
less
,greater
,less_equal
和greater_equal
,对于任何指针类型产量特在这些专业化中严格的总订单是一致的,并且也与内置运营商施加的部分订单一致<
,>
,<=
,>=
。
所以下面将被明确定义:
template<class T> auto byte_address(T& p) {
return reinterpret_cast<std::byte const*>(std::addressof(p));
}
template<class Object, class Part>
bool is_within_object(Object& object, Part& part)
{
auto first = byte_address(object);
auto last = first + sizeof(Object);
auto p = byte_address(part);
return std::less_equal<std::byte*>{}(first, p) &&
std::less<std::byte*>{}(p, last);
}
以上是 是否合法,检查的子对象的地址是否在包含对象的范围 的全部内容, 来源链接: utcz.com/qa/257571.html