有一个用于通过以下方式实现字典的类代码std::map
:
template<class Key, class Value>
class dictionary
{
public:
virtual ~dictionary() = default;
virtual const Value& get(const Key& key) const = 0;
virtual void set(const Key& key, const Value& value) = 0;
virtual bool is_set(const Key& key) const = 0;
};
template<class Key, class Value>
class Dictionary : public dictionary<Key, Value>
{
std::map<Key, Value> _key;
public:
Dictionary() = default;
Dictionary(const Dictionary&) = delete;
Dictionary& operator=(const Dictionary&) = delete;
Dictionary& operator=(Dictionary&&) = delete;
Dictionary(Dictionary&&) = delete;
~Dictionary() override = default;
public:
const Value& get(const Key& key) const override
{
const auto i = _key.find(key);
if (i == _key.end())
{
throw KeyNotFoundException<int>(key);
}
return this->_key.at(key);
}
void set(const Key& key, const Value& value) override
{
const auto i = _key.find(key);
if (i != _key.end())
{
_key.at(key) = value;
}
else _key.emplace(key, value);
}
bool is_set(const Key& key) const override
{
const auto i = _key.find(key);
return i == _key.end() ? false : true;
}
};
如何改进get
和改进代码set
?
_key.at
不需要调用,因为您手头有一个迭代器。KeyNotFoundException<int>
-int
看起来很可疑。你对
std::map.find()
. 你正在寻找一个元素,通过得到的迭代器你已经可以判断是否找到了,如果找到了,再用std::map.at()
.可以提出三个改进建议:
find
和最后检查迭代器,你可以使用方法contains
,但这是如果你想切换到 C++ 20,但同样,代码不会是最优的。find
,你得到了一个指向元素的迭代器(如果有的话),所以检查之后,if (i == _key.end())
你可以在函数的返回中引用迭代器,得到它指向的对象,不再搜索.std::map.at()
。没有元素时使用选项可以如下:在同一个方法std::out_of_range
中,捕获异常并抛出自己的异常,或者进一步发送此异常。但这里重要的是要记住,抛出和接受异常是一项相对昂贵的操作,因此选项 2 更可取。std::map
真的,如果std::map
它不仅做得很好,而且与C++ STL 库的其余部分也能很好地配合,那么你为什么要建立你的“字典”呢?