Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查子对象的地址是否在包含对象的范围内合法吗_C++_C++11_C++14_Language Lawyer_C++17 - Fatal编程技术网

C++ 检查子对象的地址是否在包含对象的范围内合法吗

C++ 检查子对象的地址是否在包含对象的范围内合法吗,c++,c++11,c++14,language-lawyer,c++17,C++,C++11,C++14,Language Lawyer,C++17,2个问题: 以下代码是否具有良好的格式和定义的行为 < L> > P>有可能实现C++的实现吗? 代码(c++11及更高版本): #包括 #包括 #包括 模板 自动到_地址(T*p){返回重新解释_cast(p);} ///测试零件是否为对象的子对象 模板 布尔是对象中的对象(对象和对象、零件和零件) { 自动优先=收件人地址(std::addressof(object)), last=第一个+尺寸(对象); 自动p=收件人地址(std::addressof(part)); 返回(第一个指针比较

2个问题:

  • 以下代码是否具有良好的格式和定义的行为

  • < L> > P>有可能实现C++的实现吗?

    代码(c++11及更高版本):

    #包括
    #包括
    #包括
    模板
    自动到_地址(T*p){返回重新解释_cast(p);}
    ///测试零件是否为对象的子对象
    模板
    布尔是对象中的对象(对象和对象、零件和零件)
    {
    自动优先=收件人地址(std::addressof(object)),
    last=第一个+尺寸(对象);
    自动p=收件人地址(std::addressof(part));
    
    返回(第一个指针比较定义在:

    将不等指针与对象进行比较的定义如下:

    • 如果两个指针指向同一数组的不同元素或其子对象,则指向下标较高的元素的指针比较大
    • 如果两个指针递归地指向同一对象的不同非静态数据成员,或指向此类成员的子对象,则如果两个成员具有相同的访问控制且其类不是并集,则指向后一个声明成员的指针会比较大
    • 否则,两个指针的比较值都不大于另一个指针
    如果两个操作数p和q比较相等,则p=q均为true,pq均为false。否则,如果指针p的比较大于指针q,则p>=q,p>q,qp均为false。否则,每个运算符的结果均未指定

    我们可以从中得出什么结论

    一个对象中有相同类型的指针的总顺序,但没有指向不同对象或具有不同访问控制的不同子对象的指针的顺序。由于缺少指针的总顺序,因此
    是在\u对象()中
    不是很有意义。在您希望它返回
    true
    的情况下,它是有效的。在您希望它返回
    false
    的情况下,这些运算符的结果是未指定的?这不是一个非常有用的结果


    也就是说,我们在这方面确实存在一个巨大的漏洞,其形式如下:

    对于模板
    less
    greater
    less\uequal
    greater\uequal
    ,任何指针类型的专门化都会产生严格的总顺序,在这些专门化之间是一致的,并且也与内置操作符
    =
    施加的偏序一致

    因此,应明确定义以下内容:

    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);
    }
    
    模板
    自动字节地址(T&p){
    返回reinterpret_cast(std::addressof(p));
    }
    模板
    布尔是对象中的对象(对象和对象、零件和零件)
    {
    自动优先=字节\地址(对象);
    自动上一次=第一次+大小(对象);
    自动p=字节地址(部分);
    返回std::less_equal{}(第一个,p)&&
    std::less{}(p,last);
    }
    
    “请注意,a和b具有不同的可见性。”否。它们具有不同的访问说明符。两者都是“可见的”对于任何明智的可视性概念来说。将事物私有化并不会使它们消失。我们谈论的是什么对象?它们是否实现了任何概念,如
    标准布局
    POD
    琐碎可复制
    ?你得到的答案越具体,你的答案就越准确。否则,答案可能只会围绕一个问题围绕可能不适用于现实世界问题的示例代码展开讨论。下面是有趣的地方:
    xy;assert(!is_in_object(y,X.get_a());
    这会触发exp.rel 3.3:“否则,两个指针的比较都不大于另一个”这是合法的,甚至是好的!这和过马路前看两边差不多。@MichaëlRoy在我的例子中,那就好了。我想检测它是一个单独分配的子对象。我的用例是序列化缓存。在[比较]:“当a重新解释为
    unsigned char*
    不会影响指针值,因此比较仍然有效。这不是一个漏洞。比较不同分配的指针的结果没有具体说明的历史原因是,在很长的时间和很遥远的土地上(好的,我编造了这个),有内存段以及“近”和“远”指针。比较后者的成本更高,但如果您可以假设后者引用了相同的内存段(如在单个alloc中)但是,由于
    less
    用于关联容器等,因此需要能够比较任意指针,即使它更昂贵。
    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);
    }