C++98 Wrapper for std::map::at()
C++98 Wrapper for std::map::at()
>我只能使用 C++98,并且无法访问与 C++11 一起添加的std::map::at()
的嵌入。
我的目标是编写一个非成员函数at()
行为类似于std::map::at()
的函数(使用 C++98)。
因此,我编写了以下非成员函数:
template<typename K, typename V>
V& at(std::map<K, V> map, K key)
{
if (map.find(key) == map.end())
throw std::out_of_range("key not found");
return map.find(key)->second;
}
我可以看到至少一个问题,那就是我的版本表现得好像我返回了副本一样(见下文)。
std::map<int,int> myMap;
myMap.insert(std::pair<int,int>(2,43));
// myMap.at(2)=44; // modifies the reference
// assert(44==myMap.at(2)); // fine
at(myMap,2)=44; // does not modify the value inside the map, why?
assert(44==myMap.at(2)); // not fine
- 如何解决此问题?
- 我的包装器还有其他问题吗?
主要问题是你正在调用未定义的行为。
您的at
按值获取地图:
V& at(std::map<K, V> map, K key)
因此,您返回的是对本地对象中项的引用,这是非常未定义的。
您应该使用引用:
V& at(std::map<K, V>& map, const K& key)
您可能还想添加 const 版本:
const V& at(const std::map<K, V>& map, const K& key)
将签名更改为
V& at(std::map<K, V>& map, K key)
您的方法中有 2 个问题:
- 您将映射实例作为值传递,因此不仅可以复制整个映射,还可以返回对该本地副本中元素的引用并生成 UB
- 您进行两次查找,这在地图上的操作非常昂贵
因此,您的代码可以是:
template<typename K, typename V>
V& at(std::map<K, V> &map, K key)
{
std::map<K,V>::iterator f = map.find(key);
if ( f == map.end())
throw std::out_of_range("key not found");
return f->second;
}
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 使用一个考虑到std::map中键值的滚动或换行的键
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 使用 at() 访问 std::map 元素是否比运算符 [] 慢?
- C++11 功能 std::map::at 编译旧版本的C++
- out_of_range使用std :: map :: at(const char*),除了使用 /02编译时
- 为什么没有透明的C++1x std::map::at?
- std::map at 函数总是抛出异常
- Disable std::map::at()
- C++98 Wrapper for std::map::at()
- 地图 [] 和 map.at 在C++中的区别
- map/unordered_map:首选find(),然后at()或try at() catch out_of_rang
- 当std::map::at超出范围时返回什么
- 是c++ 11中map标准的at() const访问器
- 在预c++0x中使用map::at()
- 在map/undered_map中使用find vs.at