我有一个类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) {};
}
答案 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
实例。