带有内存比较的 STL 映射.如何在运行时设置比较块大小

STL map with memcmp comparison. How to set comparison block size at runtime?

本文关键字:比较 运行时 设置 内存 STL 映射      更新时间:2023-10-16

我有一个类Parent,它从文件加载配置数据并在std::map中创建Child对象。Child对象由配置文件中定义的const char*映射。对于任何给定的Parent,所有子级将共享相同的密钥长度。因此,一个Parent映射的Child对象可能有8字节的键,而另一个Parent的孩子可能使用4字节的键。

使用此处描述的方法或使用其他方法,如何创建一个新的 std::map 成员对象,其比较函数依赖于仅在运行时可用的数据?

具体来说,我正在尝试使用memcmp(a, b, n);,就像前面链接的问题显示的那样,但我希望n是可变的,而不是固定在 4。

如果我还没有很好地解释我想要做什么,我会尝试把它放在代码中。如何编写compareKey,以便它使用childKeyLength来比较映射键:

class Child;
class Parent {
private:
    struct compareKey {
        bool operator()(char * const a, char * const b) {
            return memcmp(a, b, childKeyLength) < 0;
        }  
    };
    std::map<const char*, Child, compareKey> children;
    size_t childKeyLength;
public:
    Parent(size_t childKeyLength)
    : childKeyLength(childKeyLength) {};
}

如果你的键真的只是你的评论所暗示的任意二进制数据,那么也许你真正想要的是:

std::map<std::vector<char>, Child> children;

vector已经有一个实现严格弱排序的operator<,所以这很好用。

<小时 />

如果其他人拥有数据,那么我建议将长度包装到类型中并进行比较:

struct Data {
    const char* p;
    size_t len;
};
struct DataComparer {
    bool operator()(Data const& lhs, Data const& rhs) const {
        int cmp = memcmp(lhs.p, rhs.p, std::min(lhs.len, rhs.len));
        return cmp < 0 || cmp == 0 && lhs.len < rhs.len;
        // or if you're feeling feisty?
        // return std::make_tuple(memcmp(lhs.p, rhs.p, std::min(lhs.len, rhs.len)), lhs.len)
        //     < std::make_tuple(0, rhs.len);
    }
};
std::map<Data, Child, DataComparer> children;
<小时 />

如果密钥长度是固定的,那么您可以简单地将其作为比较对象的成员(而不是只是浮动在某个地方):

struct MemComparer {
    size_t length;
    bool operator()(const char* lhs, const char* rhs) const {
        return memcmp(lhs, rhs, length) < 0;
    }
};

现在,map可以以合理的方式复制 - 您只需将map构造函数传递给一个MemComparer实例。