【发布时间】:2012-10-05 23:42:31
【问题描述】:
在 C++ 中,我有一个按其名称排序的类,即 std::string。我希望std::map 或std::set 中的每个唯一名称只有一个。
我可以使用std::set,因为operator< 将按其名称对我的实例进行排序,但是,我需要按其名称查找实例。使用键是名称的映射是直截了当的,但是,我也可以使用一个集合并构造一个具有我希望查找的名称的类的虚拟实例,以在集合中定位给定类的实际实例名字。
我想我应该只使用地图以使代码直截了当,但想知道是否有办法使用该集合,因为密钥实际上是我的对象的一部分,因此避免了一些冗余。
有没有办法使用集合并能够以干净的方式通过键定位对象,或者我应该只使用地图并完成它?
这是要插入的类(草稿形式),在每个目录中都有一组节点或节点映射,以节点名称为键:
class Node {
public:
Node(Directory &parent, const std::string &name)
: _name(name),
_parent(&parent),
_isRoot(false) {
if (name.empty()) {
throw InvalidNodeNameError(name);
}
}
protected:
// This is only used for the root directory:
Node()
: _name(""),
_parent(0),
_isRoot(true) {
}
Node(const std::string &name)
: _name(name),
_parent(0),
isRoot(false) {
}
public:
virtual ~Node() {
if (parent()) {
parent()->remove(*this);
}
}
bool operator<(const Node &rhs) const {
return _name < rhs._name;
}
Directory *parent() const {
return _parent;
}
void setParent(Directory *parent) {
_parent = parent;
}
const std::string &name() const {
return _name;
}
bool isRoot() const {
return _isRoot;
}
std::string pathname() const {
std::ostringstream path;
if (parent()) {
path << parent()->pathname() << '/';
} else {
path << '/';
}
path << name();
return path.str();
}
private:
// Not defined:
Node(const Node &rhs);
Node &operator=(const Node &rhs);
private:
std::string _name;
Directory *_parent;
const bool _isRoot;
};
【问题讨论】:
-
I asked a very similar question before。实际上,所有的答案都很好。唯一的区别是你的涉及比较,而我的涉及散列 -
map与unordered_map。 -
看看你的课可能会有所帮助。
-
我认为 set 通常是作为 map 的一个特例来实现的,所以你可能不会为自己买太多的性能。一种方法可能是根据地图来实现,但提供一个界面,该界面被限制为更像“集合”,只是远不及集合本身。 IMO,这比反过来尝试包装设置要容易。