做的时候
unordered_map<pair<unsigned int, unsigned int>, unsigned int> m;
Run Code Online (Sandbox Code Playgroud)
我们得到
错误 C2338:C++ 标准未提供此类型的哈希值。
是否有内置的方法来定义 of 的哈希值std::pair,int或者我们需要手动定义它?(在这种情况下,散列可以只是(第一项的字节)(该对的第二项的字节)粘合在一起)。
注意:我使用的是 VC++ 2013。
注意2: pair<int,int>pair作为unordered_map问题的关键的答案并没有清楚地解决如何实际创建具有两个ints的散列的问题,如此处详述。
如果我有两个unordered_set具有相同内容的变量(如果已排序),但创建方式不同(例如,第一个变量仅插入了项目,第二个变量以不同的顺序插入、删除了项目等,但两个变量最终都具有相同的内容),迭代这两个变量会产生相同顺序的值吗?
附言。这个问题与迭代相同的无序集合两次的类似问题不同。
我对现代 C++ 比较陌生,并且使用外国代码库。有一个函数接受 std::unordered_map 并检查映射中是否存在键。代码大致如下
uint32_t getId(std::unordered_map<uint32_t, uint32_t> &myMap, uint32_t id)
{
if(myMap.contains(id))
{
return myMap.at(id);
}
else
{
std::cerr << "\n\n\nOut of Range error for map: "<< id << "\t not found" << std::flush;
exit(74);
}
}
Run Code Online (Sandbox Code Playgroud)
似乎调用contains()后面的at()效率很低,因为它需要双重查找。所以,我的问题是,实现这一目标最有效的方法是什么?我还有一个后续问题:假设地图相当大(~60k 元素)并且此方法被频繁调用,上述方法有多大问题?
经过一番搜索,似乎以下范例比上面的更有效,但我不确定哪个是最好的。
在构造myMap.at()内部调用try-catch
at如果键不存在,会自动抛出错误try-catch显然成本相当高,并且还限制了优化器可以对代码执行的操作使用find
try-catch开销 auto findit = myMap.find(id);
if(findit == myMap.end())
{
//error message;
exit(74);
}
else
{
return findit->first;
}
Run Code Online (Sandbox Code Playgroud) 我想根据某些条件从地图中删除一些元素:
#include <unordered_map>
#include <ranges>
#include <iostream>
int main() {
std::unordered_map<int, int> numbers = {{1,2}, {2,1}, {3,2}, {4,5}};
auto even = [](auto entry){return entry.second %2 == 0;};
for(auto& [key, val] : numbers | std::views::filter(even)) {
numbers.erase(val);
}
for(auto& [key, val] : numbers) {
std::cout << key << " " << val << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
但似乎我正在使基于范围的循环所需的迭代器无效:
4 5
3 2
1 2
Run Code Online (Sandbox Code Playgroud)
我知道如何使用迭代器显式地执行此操作,但是是否有一种基于范围的简洁方法来删除基于过滤器的元素?
我正在尝试对类使用自定义哈希结构A,该类是 an 中的关键类型,它是class 中的替代方案std::unordered_map之一。\n这是我的代码的简化版本,可以在其中重现错误:std::variantB
#include <initializer_list>\n#include <string>\n#include <unordered_map>\n#include <variant>\n\nnamespace myNamespace {\n class A;\n struct AHasher;\n class B;\n\n // ....\n\n class A {\n public:\n A(const std::string& str);\n friend bool operator==(const A& lhs, const A& rhs);\n public:\n std::string value;\n };\n\n struct AHasher {\n std::size_t operator()(const A& str) const;\n };\n\n class B {\n public:\n B();\n B(const std::string& str);\n B(const A& str);\n B(const std::initializer_list<std::pair<const A, B>> list);\n private:\n std::variant<A, std::unordered_map<A, B, AHasher>> value;\n };\n\n} // namespace myNamespace …Run Code Online (Sandbox Code Playgroud) 对于我的下一个任务,我需要使用一个非常大的哈希; 因为我有一个旧的编译器,我不能使用C++ 0x std::unordered_map.理想情况下,我需要的是reserve提前为大量物品腾出空间.我找不到这种方法boost::unordered_map:是否有任何地方或功能达到同样的目的?
2个关联容器是相同的; 我可以看到rehash函数和用于控制存储桶数量的相同构造函数,但不能看到有关许多元素的函数.
你能帮帮我吗?
我对矢量查找与地图查找感到好奇并为它编写了一个小测试程序..它看起来像矢量总是比我使用它的方式更快..我还应该考虑其他什么吗?测试是否有偏见?运行的结果在底部..它以纳秒为单位,但gcc似乎并不支持我的平台.
使用字符串进行查找当然会改变很多事情.
我正在使用的编译行是这样的:g ++ -O3 --std = c ++ 0x -o lookup lookup.cpp
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <chrono>
#include <algorithm>
unsigned dummy = 0;
class A
{
public:
A(unsigned id) : m_id(id){}
unsigned id(){ return m_id; }
void func()
{
//making sure its not optimized away
dummy++;
}
private:
unsigned m_id;
};
class B
{
public:
void func()
{
//making sure its not optimized away
dummy++;
}
};
int main()
{
std::vector<A> v;
std::unordered_map<unsigned, B> …Run Code Online (Sandbox Code Playgroud) 我有std::unordered_map我emplace()的目的是通过:
my_map.emplace(std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(value1, value2));
Run Code Online (Sandbox Code Playgroud)
这在运行时期间的某个时刻失败,false返回元组的第二个位置.有没有办法获得有关正在发生的事情的更多信息?top记忆没有任何问题.
我不清楚是否unordered_map允许在做某事时进行重组erase()
很明显,在insert()使所有迭代器和引用无效的过程中可能会发生重新散列:
http://en.cppreference.com/w/cpp/container/unordered_map/insert
但erase()似乎保留所有迭代器和引用,除了擦除的那些:
http://en.cppreference.com/w/cpp/container/unordered_map/erase
但是,最后一页和标准表明erase()最差的执行时间是O(size).什么操作可以花费线性时间来完成而不是以使迭代器无效的方式修改容器?
这篇文章表明在删除过程中迭代器无效:http: //kera.name/articles/2011/06/iterator-invalidation-rules-c0x/
我还读到某个地方,未来的提案将允许重新开始erase().真的吗?
如果确实发生了重复,那么旧的迭代和擦除算法是错的吗?
考虑以下代码:
static std::unordered_map<std::string, Info> stringCollection;
auto& [it, inserted] = stringCollection.try_emplace(pString);
if (inserted) {
it->second.str = &it->first;
}
return it->second;
Run Code Online (Sandbox Code Playgroud)
该行it->second.str = &it->first应该复制键(指针)的地址-但我似乎无法验证是否会出现这种情况(找不到引用)。基本上it->first给我副本还是参考?
c++ ×10
unordered-map ×10
c++11 ×3
c++17 ×2
dictionary ×1
hash ×1
hashmap ×1
map ×1
performance ×1
std ×1
std-pair ×1
std-ranges ×1
vector ×1