我想列出
struct object {
std::string unique_name;
some_type more_data;
other_type member_functions() const; // many such member functions
};
使用unique_name
作为索引。不幸的是,我不能使用
using object_table = std::unordered_set<object>;
由于无法搜索具有名称的对象,因为object_table::find()
仅允许输入object
类型的搜索键:
class objects {
object_table _table;
public:
object const&operator[](std::string const&name) const
{
// cannot be implemented using object_table::find()
}
};
那我该怎么办?
到目前为止,我的尴尬解决方案是
using object_table = std::unordered_map<std::string, some_type>;
struct object : object_table::value_type
{
std::string const&name() const { return first; }
other_type member_functions() const;
private:
using object_table::value_type::first;
using object_table::value_type::second;
};
class objects {
object_table _table;
public:
object const&operator[](std::string const&name) const
{
auto it = _table.find(name);
if(it == _table.end())
throw runtime_error("cannot find object '"+name+'\'');
return *static_cast<const object*>(std::addressof(*it)); // is cast legal?
}
};
这样做的代价是将object
与std::pair<std::string, some_type>
一起麻烦地修补在一起。
答案 0 :(得分:3)
由于每个对象的名称都是唯一的,因此您只能将unique_name
的哈希值用作对象的哈希值。使用
namespace std
{
template<> struct hash<object>
{
typedef object argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& o) const noexcept
{
return std::hash<std::string>{}(o.unique_name);
}
};
}
bool operator ==(const object& lhs, const object& rhs)
{
return lhs.unique_name == rhs.unique_name;
}
可以让您编写类似
的查找代码using object_table = std::unordered_set<object>;
class objects
{
object_table _table;
public:
object const&operator[](std::string const&name) const
{
if (auto it = object_table.find(object{name}); it != object_table.end())
return *it
else
throw();
}
};
这确实要求object
可以从单个std::string
进行构造,并且必须用于初始化unique_name
。