我std::map用来存储很多元素(元素对),我有一点"怀疑".更重要的是有效地遍历我所有的元素std::map,iterator或reverse_iterator?
这是在地图中提供唯一键的合适方法吗?换句话说,键是由uuid中包含的唯一值构成的,还是由指向uuid_tstruct 的指针构成的?一个问题是,当我不关心容器内的按键排序时,是否有更高效的容器?
#include <uuid/uuid.h>
int main(int argc, char **argv)
{
std::map<uuid_t,int> myMap;
uuid_t id1;
uuid_t id2;
uuid_generate( (unsigned char *)&id1 );
uuid_generate( (unsigned char *)&id2 );
myMap[id1] = 5;
myMap[id2] = 4;
}
Run Code Online (Sandbox Code Playgroud) 使用std::map时析构函数是否会在元素上调用std::map::clear?
我尝试调试,std::map<string,string>但是看不到std::string析构函数被调用。任何人都可以帮助我理解吗?
文档指出它被调用了,但是我没有注意到。
我有一个名为'Card'的类,我试图将它的一些对象存储在std :: map Card.hpp中:
class Card
{
public:
enum ValueType { NOVALUE, ACE };
enum FaceType { NOFACE, CLUBS };
Card(const ValueType & _value, const FaceType & _face);
Card(const Card & _card);
private:
ValueType m_value;
FaceType m_face;
};
Run Code Online (Sandbox Code Playgroud)
以下是我存储和访问它的方法:Deck.hpp:
#include <map>
class Card;
class Deck
{
public:
Deck();
std::size_t length() const;
Card get_card(const int & _num);
private:
std::map<int, Card> m_deck;
};
Run Code Online (Sandbox Code Playgroud)
Deck.cpp:
#include "Card.hpp"
Deck::Deck()
{
m_deck.insert(std::pair<int, Card>(0, Card(Card::NOVALUE, Card::NOFACE)));
m_deck.insert(std::pair<int, Card>(1, Card(Card::ACE, Card::CLUBS)));
}
std::size_t Deck::length() const
{
return …Run Code Online (Sandbox Code Playgroud) 这是Valgrind的输出:
==6519== at 0x4C25885: operator new(unsigned long) (vg_replace_malloc.c:319)
==6519== by 0x4EE65D8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (new_allocator.h:104)
==6519== by 0x4EE7CE0: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (basic_string.tcc:138)
==6519== by 0x4EE80F7: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (basic_string.h:1725)
==6519== by 0x41C399: pilInpOpts::pilInpOpts() (pilInpOpts.cpp:12)
==6519== by 0x403A55: main (main.cpp:32)
Run Code Online (Sandbox Code Playgroud)
对于地图中的每个条目重复相同的错误.
main.cpp第32行是:
pilInpOpts input;
Run Code Online (Sandbox Code Playgroud)
pilInpOpts的第12行是构造函数的一部分:
#include "pilInpOpts.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
pilInpOpts::pilInpOpts()
{
// create the map of options, put in alphabetical order to …Run Code Online (Sandbox Code Playgroud) 如何在地图中使用复数作为键?这是一个不会编译的小示例:
#include <complex>
#include <map>
int main() {
std::complex<double> zero = 0.0;
std::map<std::complex<double>, int> theMap;
return (theMap.count(zero));
}
Run Code Online (Sandbox Code Playgroud)
我可以创建没有错误的地图,但是任何方法(例如,count上面的调用以及find,[]运算符insert等)都会生成编译时错误。就我的理解而言,这绝对是一个问题,因为使用clang和g ++可以获得类似的结果。
看起来编译器无法比较两个复数。我创建了所有比较运算符(例如bool operator< (const std::complex & lhs, const std::complex & rhs) {return (std::norm(lhs) < std::norm(rhs));}),用于比较复数(只要您不介意3 < -5为,这对即可map),但编译器不会选择它。
我对unordered_map也有类似的问题(没有哈希值complex<double>)
#include <iostream>
#include <map>
int main(int argc, char** argv)
{
std::map<int, int> map;
map.emplace(1, 1);
auto reverse_iter = map.rbegin();
std::cout << reverse_iter->first << ", " << reverse_iter->second << std::endl;
map.emplace(2, 2);
std::cout << reverse_iter->first << ", " << reverse_iter->second << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印出:
1, 1
2, 2
Run Code Online (Sandbox Code Playgroud)
根据标准,这真的应该发生吗?我没有触及reverse_iter,但它指向的值正在改变.我认为std :: map中的迭代器应该是安全的,不会插入.然而,似乎在决定reverse_iter不是要指向我告诉它的价值,而是指"在这个时间点发生在地图末尾的任何事情".
更新:进一步的信息,万一重要:这似乎不会发生前进迭代器(在任何情况下,我似乎可以找到),我的gcc版本是5.1.1-4.
我有一个std :: map对象map<string , Property*> _propertyMap,其中string是属性的名称并Property*包含属性值.
我需要处理属性值并将它们转换为特定的数据格式 - 每个属性都有自己的格式,例如.如果地图初始化如下:
_propertyMap["id"] = new Property(Property::UUID, "12345678");
_propertyMap["name"] = new Property(Property::STRING, "name");
....
Run Code Online (Sandbox Code Playgroud)
然后"id"应该处理不同于"name"等.
这意味着我需要在地图中查找每个属性并相应地处理其值.
我想到了两种方法.
一,使用std::map::find方法获取特定属性,如:
map<string , Property*>::iterator it1 = _propertyMap.find("id");
if(it1 != _propertyMap.end())
{
//element found - process id values
}
map<string , Property*>::iterator it2 = _propertyMap.find("name");
if(it2 != _propertyMap.end())
{
//element found - process name values
}
....
Run Code Online (Sandbox Code Playgroud)
二,迭代地图,并为每个条目检查属性的名称是什么,并相应地继续:
for (it = _propertyMap.begin(); it != _propertyMap.end(); ++it …Run Code Online (Sandbox Code Playgroud) 我正在使用std::map来存储大约2000万个条目。如果存储它们时没有任何容器开销,那么将需要大约650MB的内存。但是,由于它们是使用存储的std::map,因此会占用约15GB的内存(即过多)。
我使用an的原因std::map是因为我需要找到等于/大于/小于的键x。这就是为什么类似的东西sparsehash行不通的原因(因为使用它,我无法通过比较找到密钥)。
是否有替代使用std::map(或通常使用有序映射)的方法,从而减少了内存使用量?
编辑:写性能远高于读取性能更重要。它可能只会读取约10个条目,但我不知道它将读取哪些条目。
我试图理解除了auto循环之外的“理论”
std :: map
C ++中的元素。我有std::map一个std::stringKEY和一个vector<std:string>作为价值。我可以通过以下方式访问其元素:
for ( auto &element : myMap ) {
std::cout << element.first << ": " << '\t';
for ( std::string subElement : element.second ) std::cout << subElement << ", ";
}
}
Run Code Online (Sandbox Code Playgroud)
至于vector<string>元素上的循环,我知道我可以放“ auto”而不是“ std :: string”。但是在这种情况下,地图的等效值是多少?我经过研究和搜索,在那篇文章中发现每个地图元素都以
map <K,V> :: value_type
但是我怎么写下来呢?我试过了:
for ( std::map<std::string, vector<std::string>> &pz : myMap ) {
// print ...
}
Run Code Online (Sandbox Code Playgroud)
和类似的东西,但是它们根本不起作用。
c++ ×10
stdmap ×10
c++11 ×2
dictionary ×2
performance ×2
stdstring ×2
auto ×1
coding-style ×1
database ×1
iterator ×1
memory ×1
std ×1
stl ×1
uuid ×1
valgrind ×1