包装地图访问,聪明还是愚蠢
wrapping map access, smart or stupid?
我正在访问一段非性能关键代码中的许多映射。我不想写通常的发现/=结束所有的时间来检查丢失的钥匙。我也不想盲目使用[]并获取默认值。下面的包装器函数是聪明的还是愚蠢的?有没有更简单的方法?有没有我没有考虑的副作用?
template<typename M>
static typename M::mapped_type getMapValue(const M& m, typename M::key_type key) {
typename M::const_iterator it = m.find(key);
if (it != m.end()) {
return it->second;
} else {
std::cerr << "Key: " << key << " not found!" << std::endl;
std::cerr << "Returning default value." << std::endl;
return typename M::mapped_type();
}
}
我建议使用std::map::at
,然后客户端代码必须决定如何处理从具有不在映射中的键的调用引发的任何std::out_of_range
异常。
std::map<std::string, int> m;
....
int n = m.at("hello!");
智能
封装std
容器通常是个好主意,因为如果您愿意,它可以让您在将来交换它们。
然而,返回默认值是正确的行为吗?这可能是你的情况,但在大多数情况下,它不会是。
每当STL接口对于某些程序逻辑变得繁琐时,我倾向于包装整个容器,而不仅仅是访问单个函数。通常,我会从现有的容器类型中私下派生,并再次公开我需要的部分。此外,我添加了我需要的实际接口,例如运算符[],用于const-map之类的对象:
struct mycontainer:
private map<string, string>
{
typedef map<string, string> base;
using base::iterator;
using base::const_iterator;
using base::begin;
using base::end;
string const& operator[](string const& k) const
{
const_iterator it = find(k);
if(it == end())
throw runtime_error("lookup failure");
return it->second;
}
};
注:
- 如果您需要特殊的迭代器,Boost中有一个帮助程序库,可以轻松创建自定义迭代器类型
- 您还可以显著更改界面,例如,返回默认值而不将其添加到映射中,或返回boost::可选。后者是IMHO,这是一种的方法,可以在一步中轻松检查是否存在并检索值
如果这个想法是检查的,那么你可能想要这样的东西:
if (theMap.count(theKey)) {
doSomethingWith(theMap[theKey]);
} else {
doSomethingDefault();
}
名称计数非常尴尬,因为如果元素存在,它只返回true,如果不存在,则返回false。我认为它应该与一些支持每个键多个值的容器保持一致,但后来他们从未编写过那个容器。仅仅将"count"重命名为"contains"可能不值得包装映射。
我认为当找不到元素时,最好抛出一个异常。谁来监视你的程序,不管怎样,它会打印出所有这些警告?
此外,考虑通过const引用获取密钥,因为std::map
会这样做。
相关文章:
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?
- 以C++访问矢量中的地图元素
- 如何访问具有地图的2D矢量?
- 如何从地图访问数组的元素?
- 如何访问整个地图的值
- std::在地图上查找无法正常工作并循环访问地图的键和值
- 无法循环访问标准::地图
- 尝试访问地图中元素时的错误
- 简单的 CPP 地图存储和访问无法按预期工作
- 从地图擦除后访问指针
- 从地图访问对象会导致新对象C 的实例化
- 在C++中访问和插入地图的地图(嵌套地图)
- 无法访问/存储地图中的游戏状态对象
- 如何从公共函数成员访问地图私有成员
- 以对为键访问地图
- 如何避免地图访问的常量投射?
- C++地图访问和迭代所花费的时间
- C++加快地图访问速度
- 在c++地图访问上的segfault
- 包装地图访问,聪明还是愚蠢