假设如下:
struct C {
... // lots of other stuff
int get(int key) const { return m.at(key); } // This will never throw
private:
std::unordered_map<int, int> m;
};
由于应用程序的工作方式,我知道get
永远不会抛出。我想尽快get
。所以,我想不检查访问权限,即我想写类似 return m[key]
.当然,我不能在保持get
恒定的同时准确地写出这一点。但是,我想保持get
常量,因为它在逻辑上是常量。
这是我想出的唯一(丑陋的)解决方案:
struct C {
... // lots of other stuff
int get(int key) const { return const_cast<C *>(this)->m[key]; }
private:
std::unordered_map<int, int> m;
};
有没有更好的方法?
一种方法是使用std::unordered_map::find
:
struct C {
... // lots of other stuff
int get(int key) const { return m.find(key)->second; }
private:
std::unordered_map<int, int> m;
};
我反对这个问题背后的推理。与捕获由于未知key
引起的错误相关的开销(map.at()
vs map[]
)与首先查找key
的成本相比可能很小。然而,您愿意冒运行时错误的严重风险,只是为了获得可能甚至尚未验证/测量的边际效率优势。您可能认为您知道key
始终包含在映射中,但也许未来的代码更改(包括其他人引入的错误)可能会改变这一点?
如果你真的知道,那么你应该使用
map.find(key)->second;
这使得错误明确,如果返回的迭代器无效(即等于 map.end()
)。您可以在预生产代码中使用assert
,即
auto it = map.find(key);
assert(it!=map.end());
return it->second;
在生产代码中(当assert
是空宏时)被删除。