使用未定义的多重映射
Playing with unordered_multimap
所以,伙计们,我玩std::unordered multimap
只是为了好玩。我想存储(在本例中)unsigned short
s,其中包含一个自定义的hash和equal。
有趣的部分是什么?有两个相等的项,如果它们都是偶数或奇数。
因此,据我所知,我不能使用std::unordered_map
,即使实际值不同:自定义谓词表示不同。(很明显,如果我错了,请纠正我!)
因此,回顾一下:我存储不同的整数,因此存储不同的散列,但它们在谓词下的值可能相同。
#include <iostream>
#include <unordered_map>
class tt
{
public:
tt(const unsigned short v = 0) : i(v) { };
unsigned short i;
};
class tt_hash
{
public:
size_t operator()(const tt &v) const
{
auto f = std::hash<unsigned short>();
return f(v.i);
};
};
class tt_equal
{
public:
bool operator()(const tt &u, const tt &v) const
{
return (u.i % 2) == (v.i % 2);
};
};
typedef std::unordered_multimap<tt, bool, tt_hash, tt_equal> mymap;
// Print all values that match a criteria
void f(const mymap &m, unsigned short c)
{
auto range = m.equal_range(c);
auto target = range.first;
if (target == m.end())
{
std::cout << "not found : " << (int) c << std::endl;
}
else
{
for (auto i = target; i != range.second; i++)
std::cout << "there is : " << (int) i->first.i << " : " << i->second << std::endl;
}
}
int main(int argc, const char * argv[])
{
mymap m;
m.emplace(std::make_pair(tt(3), false));
m.emplace(std::make_pair(tt(10), true));
m.emplace(std::make_pair(tt(4), true));
m.emplace(std::make_pair(tt(23), false));
std::cout << "size " << m.size() << std::endl;
std::cout << "buck " << m.bucket_count() << std::endl;
int c = 0;
for (auto i = m.begin(); i != m.end(); i++)
std::cout << "# " << c++ << " : " << (int) i->first.i << " : " << i->second << std::endl;
f(m, 3);
return 0;
}
因此,当我执行上面的代码时,我会找到正确的值,3、10、4、23(当然不是按这个顺序)。
出乎意料的是,当打印所有匹配3调用f()
的值时,我得到了两个答案,3和23;但当我要求1000时,我本以为会打印出所有的偶数,但我错了:
size 4
buck 5
# 0 : 4 : 1
# 1 : 10 : 1
# 2 : 3 : 0
# 3 : 23 : 0
there is : 10 : 1
我是不是遗漏了什么?(答案显然是肯定的)
您所做的是未定义的行为:相等的元素应该具有相等的哈希值。根据标准(强调矿)
23.2.5无序关联容器[unord.req]
5如果当传递这些时,容器的键相等谓词返回true值如果k1和k2相等,则容器的哈希函数应为两者返回相同的值。
由于您根据模2定义了等价性,因此还需要对传递的整数的模2使用散列函数。这也意味着一旦您有2个以上的元素,就需要std::unordered_multimap
。
相关文章:
- 编译C++时未定义的引用
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- c++11评估顺序(未定义的行为)
- 有哪些好的做法可以帮助在未定义的映射和矢量中预防std::bad_alloc
- std::映射运算符[]--未定义的行为
- yaml-cpp迭代具有未定义值的映射的最简单方法
- C++ 对自定义映射迭代器函数的未定义引用
- 增强将未定义的映射保存到磁盘的能力
- 为一个未定义的映射打开MP/_gno_parallel
- 使用未定义的多重映射
- c++模板类静态const变量成员作为映射键给出未定义引用
- C++,如何遍历一个未定义的映射
- 定时矢量与映射与未定义映射查找