在C++中是否有一种可移植的替代指针关系比较?

sim*_*onz 1 c++ comparison pointers

我缺乏语言的行业经验.但是在业余时间,我遇到了几个需要比较指针的地方,最好是标准定义的行为.

第一种情况,如果我决定在我的应用程序中使用有序二叉树作为容器(而不是哈希表)并且我希望相等是对象的标识(即相等意味着相同的实例),那么我发现没有可移植的方法来做到这一点.

其次,如果我想测试"完整对象"和它们的子对象之间的包含关系,我似乎再没有可移植的方法.那就是如果我有两个void*指针"p"和"q",并且我有"q"所指向的对象的大小,我看不出来测试"p"是否是非静态成员变量"q"与否.我没有从标准中的第5.9段("关系运营商")中找到鼓励.例如,后一种情况出现在这个提升论坛帖子的垃圾收集器中.我喜欢这个一般的想法并开始探索它,但是某些部分似乎以不可移植的方式使用指针和分配语义.

那就是我想知道如何contains从以下代码中获取该函数的可移植性:

#include <stddef.h>
#include <assert.h>

struct A {
    int x;
} a;

struct B {
    int y;
} b;

bool contains(const void *outer, size_t size, const void *inner)
{
    return (outer <= inner) &&
        (inner < static_cast<const char *>(outer) + size);
}

int main()
{
    assert(contains(&a, sizeof(a), &a.x));
    assert(contains(&b, sizeof(b), &b.y));
    assert(!contains(&a, sizeof(a), &b.y));
    assert(!contains(&b, sizeof(b), &a.x));
}
Run Code Online (Sandbox Code Playgroud)

谢谢和最好的问候.

PS:
好的,在再次查阅标准之后,我看到它明确地说明了,正如GMan在他的回答中所说的那样less,函子如less_equal指针和提供指针的总排序.我想这也暗示顺序将与内置的比较符一致<<=,但是这点可以更迂腐解决.当指针不指向同一数组或同一对象的子对象时,内置运算符是不可预测的.我的意思是,这个总顺序中的独特性测试是什么 - 指针的二进制表示?例如,如果没有明确定义的方式与内置运算符进行比较,那么void*指针的总顺序中的不相同是什么意思?

对于具有相同访问控制的成员变量,标准在内存中定义它们的顺序,即通过指针比较观察时.它是对象类型定义中的外观顺序.从内置比较运算符的角度来看,第一个成员变量的地址最小,最后一个成员变量的地址最大.另外,在关于类型的部分中,陈述了"平凡可复制类型"的对象将在&操作符的值和后面的sizeof字符之间的范围内布置在存储器中.现在让我们假设仿函数提供了指向不同对象的指针的总顺序.这是不是意味着,即使无意中,标准意味着上面代码段的行为,如果使用函子代替函数中的内置运算符contains

只是想明确一点 - 如果标准有遗漏,或者只是需要澄清,或者它为指针比较的实现留下了灵活性.

GMa*_*ckG 6

我不太确定你要求的是什么(即你究竟想要完成什么?),但我认为这是你想知道的:

关系算符greater,greater_equal,less,并less_equal在规定<functional>的产量总体排序为任何指针类型,即使内置的关系运算符不.

那是:

#include <functional>
#include <iostream>

int main()
{
    int i, *j = &i;    
    int k, *l = &k;

    std::cout << std::boolalpha << std::less<int*>()(j, l) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

定义明确.(注意输出是实现定义的,但你保证整体排序.)

关联容器谓词默认为std::less,所以可以使用指针作为键.