使用下面的代码,我在MSVC中得到一个非常令人困惑的错误,似乎建议将键类型(std :: tuple)转换为std :: string.
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <unordered_map>
typedef std::tuple<std::string,int,char> key_t;
struct key_hash : public std::unary_function<key_t, std::size_t>
{
std::size_t operator()(const key_t& k) const
{
return std::get<0>(k)[0] ^ std::get<1>(k) ^ std::get<2>(k);
}
};
struct key_equal : public std::binary_function<key_t, key_t, bool>
{
bool operator()(const key_t& v0, const key_t& v1) const
{
return (
std::get<0>(v0) == std::get<0>(v1) &&
std::get<1>(v0) == std::get<1>(v1) &&
std::get<2>(v0) == std::get<2>(v1)
);
}
};
struct data
{
std::string x;
};
typedef std::unordered_map<key_t,data,key_hash,key_equal> …Run Code Online (Sandbox Code Playgroud) 我有一个没有默认构造函数std::unordered_map的value_type所以我不能执行以下操作
auto k = get_key();
auto& v = my_map[k];
Run Code Online (Sandbox Code Playgroud)
我最终编写了一个辅助函数
value_type& get_value(key_type& key)
{
return std::get<0>(my_map.emplace(
std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(args_to_construct_value)
))->second;
}
Run Code Online (Sandbox Code Playgroud)
但是性能明显更差(即value_type的构造函数出现在perf中),而不是以下版本.
value_type& get_value(key_type& key)
{
auto it = my_map.find(key);
if (it == my_map.end())
return std::get<0>(my_map.emplace(
std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(args_to_construct_value)
))->second;
else
return it->second;
}
Run Code Online (Sandbox Code Playgroud)
我从std :: unordered_map :: emplace对象创建中读取了emplace需要构造对象以查看是否存在.但是,在返回之前,emplace正在检查地图中是否存在此键值对.
我用错误的方式使用emplace吗?是否有一个更好的模式我应该遵循:
谢谢
我有一个Java程序,我想将其转换为C++.因此,LinkedhashmapJava代码中使用了一种数据结构,我想将其转换为C++.LinkedHashmapC++中是否有等效的数据类型?
我尝试使用std::unordered_map它,但它不保持插入的顺序.
我正在使用 GCC 7.3.1,但也在coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:
g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
Run Code Online (Sandbox Code Playgroud)
这是rai.cpp:
#include <iostream>
#include <unordered_map>
int main()
{
try
{
struct MyComp {
bool operator()(const std::string&, const std::string&) const {
throw std::runtime_error("Nonono");
}
};
std::unordered_map<std::string, std::string, std::hash<std::string>, MyComp> mymap;
mymap.insert(std::make_pair("Hello", "There"));
mymap.insert(std::make_pair("Hello", "There")); // Hash match forces compare
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
运行它的结果是:
> ./a.out
Caught exception: Nonono
=================================================================
==72432==ERROR: LeakSanitizer: detected memory leaks
Direct …Run Code Online (Sandbox Code Playgroud) 这是场景:
1)使用一个unordered_map<int, vector<MyClass*>*>让我们说我添加键1,2,... 8
2)所有键都在程序初始化时设置了向量,并且没有添加或删除
3)我有8个线程,其中thread1访问键[1] ,thread2访问键[2],... thread8访问键[8](即线程号只能访问该键号而不能访问其他键)
有时我会将值向量*重新分配给另一个堆分配的集合.(即thread1执行key[1] = new vector<MyClass*>)
我相信这将是线程安全的,我是否正确?如果没有,我想我会使用concurrent_unordered_map.
谢谢.
根据标准,std::hash课堂上不支持容器(更不用说无序容器)了.所以我想知道如何实现这一点.我有的是:
std::unordered_map<std::wstring, std::wstring> _properties;
std::wstring _class;
Run Code Online (Sandbox Code Playgroud)
我想过迭代条目,计算键和值的单个哈希值(via std::hash<std::wstring>)并以某种方式连接结果.
如果没有定义地图中的顺序,那么这样做的好方法是什么?
注意:我不想使用boost.
提出了一个简单的异或,所以它会是这样的:
size_t MyClass::GetHashCode()
{
std::hash<std::wstring> stringHash;
size_t mapHash = 0;
for (auto property : _properties)
mapHash ^= stringHash(property.first) ^ stringHash(property.second);
return ((_class.empty() ? 0 : stringHash(_class)) * 397) ^ mapHash;
}
Run Code Online (Sandbox Code Playgroud)
?
我真的不确定这个简单的XOR是否足够.
为什么在下面的哈希函数(返回常量0)似乎没有产生任何影响?
由于散列函数返回常量,我期望输出所有值为3.但是std::vector,无论我的散列函数是否为常量,它似乎都将值唯一映射到唯一值.
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
// Hash returning always zero.
class TVectorHash {
public:
std::size_t operator()(const std::vector<int> &p) const {
return 0;
}
};
int main ()
{
std::unordered_map<std::vector<int> ,int, TVectorHash> table;
std::vector<int> value1({0,1});
std::vector<int> value2({1,0});
std::vector<int> value3({1,1});
table[value1]=1;
table[value2]=2;
table[value3]=3;
std::cout << "\n1=" << table[value1];
std::cout << "\n2=" << table[value2];
std::cout << "\n3=" << table[value3];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
获得的输出:
1=1
2=2
3=3
Run Code Online (Sandbox Code Playgroud)
预期产量:
1=3
2=3
3=3
Run Code Online (Sandbox Code Playgroud)
我对哈希有什么看法?
我不明白为什么我不能unordered_map用一个array<int,3>键作为键类型:
#include <unordered_map>
using namespace std;
int main() {
array<int,3> key = {0,1,2};
unordered_map< array<int,3> , int > test;
test[key] = 2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到一个很长的错误,最相关的部分是
main.cpp:11:9: error: no match for ‘operator[]’ (operand types are std::unordered_map<std::array<int, 3ul>, int>’ and ‘std::array<int, 3ul>’)
test[key] = 2;
^
Run Code Online (Sandbox Code Playgroud)
数组是否因为错过了一些要求而没有资格成为密钥?
我有一个C++代码,我在实例化一个unordered_map,然后使用cout打印它的值.这很好用.但是,当我尝试在gdb中运行它并打印unordered_map的值时,这给了我错误.下面是代码片段:
std::unordered_map<std::string,int> mymap = {
{ "Mars", 3000},
{ "Saturn", 60000},
{ "Jupiter", 70000 } };
std::cout<< mymap.at("Mars");
std::cout<< mymap["Mars"];
Run Code Online (Sandbox Code Playgroud)
上面的两个cout语句都打印了密钥"Mars"的unordered_map值.但是,当我使用gdb然后尝试使用以下语句在关键字"Mars"上打印mymap的值时,我会收到错误.
(gdb) print mymap.at("Mars")
Cannot resolve method std::unordered_map<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, int,
std::hash<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >, std::equal_to<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >,
std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, int> > >::at to any overloaded instance
(gdb) print mymap["Mars"]
Cannot resolve function operator[] to any overloaded instance
Run Code Online (Sandbox Code Playgroud)
我使用gdb时没有出错.
我已经尝试在gdb中使用whatis mymap来查看mymap是否存在于当前上下文中并且它表示它存在.此外,我尝试初始化一个int变量并在gdb中打印它并打印它.我不明白unordered_map有什么问题.
我使用下面的语句来生成可执行文件
gsrivas4@TitanX01:~/lcode1$ g++ -std=gnu++11 -O0 -g test1.cpp -o test1.out
Run Code Online (Sandbox Code Playgroud) 在使用迭代器迭代地图时,在unordered_map中以特定顺序插入的键是否会以相同的顺序出现?
例如:如果我们在B中插入(4,3),(2,5),(6,7)并且迭代如下:
for(auto it=B.begin();it!=B.end();it++) {
cout<<(it->first);
}
Run Code Online (Sandbox Code Playgroud)
会给我们4,2,6或钥匙可以按任何顺序出现吗?
unordered-map ×10
c++ ×9
c++11 ×6
stl ×3
hash ×2
emplace ×1
gcc ×1
gdb ×1
performance ×1
tuples ×1