STL映射与memcmp比较。如何在运行时设置比较块大小?

时间:2016-05-26 20:16:43

标签: c++ dictionary stl

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

如何使用方法described here或使用其他方法创建一个新的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) {};
}

1 个答案:

答案 0 :(得分:5)

如果您的密钥实际上只是您的评论所暗示的任意二进制数据,那么您真正想要的可能是:

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实例。