我是否正确地假设向std :: map添加/删除元素不会影响其他元素(即使它们在内存中重新定位),以便以下是安全的:
我查看了有关容器信息的各个站点,但只发现了迭代器失效的情况,我已经知道...
std::map<std::string,std::string> map;
PopulateMap(map);
std::string &a= map["x"];
AddMoreData(map);
RemoveRandomKeysExceptX(map);
map["x"] = "foo";
std::cout << a << " " << map["x"] << std::endl;//prints "foo foo"
a = "bar";
std::cout << a << " " << map["x"] << std::endl;//prints "bar bar"
Run Code Online (Sandbox Code Playgroud)
我在VC9上测试了一些类似的代码,但这似乎不起作用,但这并不意味着我不仅仅是幸运,也不是因为编译器没有变化.
特定
std::map<int,std::string> myMap;
fillMyMapWithStuff(myMap);
// modify key values - I need to add a constant value to each key
for (std::map<int,std::string>::iterator mi=myMap.begin(); mi != myMap.end(); ++mi)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
什么是一个好方法应用一些重新索引?我必须删除旧条目并使用新密钥和旧值添加新条目吗?
我看不出为什么我的程序漏了,也许你可以发现它.
typedef boost::shared_ptr < std::string > StringPtr;
typedef std::pair < HWND, StringPtr > WMapPair;
typedef std::map < HWND, StringPtr > WindowMap;
// this callback populates the WindowMap (m_Windows) by adding a WMapPair each time
BOOL CALLBACK EnumWindowsCallback( HWND hWnd )
{
// adds this window to the WindowMap, along with its title text
BOOL bRetVal = FALSE;
int nTextLen = 0;
char* sWindowText = NULL;
if( ! ::IsWindow( hWnd ) )
return FALSE;
nTextLen = GetWindowTextLength( hWnd );
if( ! …Run Code Online (Sandbox Code Playgroud) 显示如何迭代a的示例std::map通常是这样的:
MapType::const_iterator end = data.end();
for (MapType::const_iterator it = data.begin(); it != end; ++it)
Run Code Online (Sandbox Code Playgroud)
即它用来++it代替it++.有什么理由吗?如果我使用它会有任何问题it++吗?
我正在寻找std :: map <long,int>的简约替代品,它将进入Windows内核驱动程序,所以它应该非常快......预计它将保持相对较小(工作集中约200)的量键和大量的插入.
寻找可以降低关键搜索成本的解决方案.
例如,计算书中单词的出现次数,我看到有人简单地写道:
map<string, int> count;
string s;
while (cin >> s) count[s]++;
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?我在我的机器上测试过,看起来如此.但保证初始化为零吗?如果不是,我会想象这样的代码:
map<string, int> count;
string s;
while (cin >> s)
if (count.find(s) != count.end()) count[s]++;
else count[s] = 1;
Run Code Online (Sandbox Code Playgroud) 我有一堆完整的重复数据,我想消除重复.你知道,例如[1,1,3,5,5,5,7]变成[1,3,5,7].
看起来我可以使用std :: map或std :: set来处理这个问题.但是我不确定(a)是否只是将所有值插入容器中,或者(b)检查它们是否已经存在于容器中并且仅在它们不存在时插入 - 是否插入非常有效?即使有更好的方法......你能建议一个快速的方法吗?
另一个问题 - 如果我存储在其中的数据不像整数那么简单,而是一个自定义类,std :: map如何管理以正确存储(哈希?)数据以便通过运算符快速访问[ ]?
这个问题直接与使用char作为stdmap中的键有关.
我理解传入的比较函数的作用以及为什么char *类型作为键需要它.但是,我不确定更新实际上是如何工作的.
我很好奇你要更新密钥的情况.如何std::map知道如何比较之间的相等性const char *,cmp_str只告诉map将键插入到树中的顺序.
我已经对stl_tree.h代码进行了一些挖掘(从这里开始),但是找不到多少.我唯一的猜测是它做了直接记忆比较.
我对underling stl_tree类如何处理这种情况感兴趣,或者它是否一直没有正确处理它,什么边缘情况会破坏?
码
#include <map>
#include <iostream>
#include <cstring>
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
int main ( int argc, char ** argv )
{
std::map<const char*, int, cmp_str> map;
map["aa"] = 1;
map["ca"] = 2;
map["ea"] = 3;
map["ba"] = 4;
map["ba"] = 5;
map["bb"] …Run Code Online (Sandbox Code Playgroud) 我有一个Person类,它有一个nameproperty(std::string).
我想创建一个查找表,一个std::unordered_map,所以我可以找到一个Person名字.但是,鉴于a Person,我也希望能够得到他们的名字.
这需要存储name两次 - 一次作为地图的键,一次存储在人物对象内,如下面的代码所示.
由于我有很多Persons一次加载到内存中,我不希望两次存储它们的名称的开销.
我已经尝试在Person类中使用键的引用/指针,但这会产生问题,因为映射似乎在修改时重新调整其数据,并且引用变为无效.
我也尝试过使用std::unordered_set,但这意味着我Person每次想要执行查找时都需要构造一个完整的对象.
是否有任何方法可以使无序映射的键和值共享相同的数据?
#include <iostream>
#include <unordered_map>
class Person
{
private:
const std::string _name;
public:
Person( const std::string& name ) : _name( name )
{
}
const std::string& get_name() const
{
return _name;
}
};
int main()
{
auto my_set = std::unordered_map<std::string, std::shared_ptr<Person>>();
my_set.insert( { "alice", std::shared_ptr<Person>( new Person( "alice" )) } …Run Code Online (Sandbox Code Playgroud) 我有一张int -> { basic types }我需要存储的地图.
我想简单地创建一个struct { int f1, int f2; };并直接存储值,在商店中就地构建结构.我不希望有任何重复的键,所以try_emplace看起来很理想.
我写了这段代码:
// mcve.cpp
#include <map>
#include <string>
struct various { int f1, f2; };
using map_t = std::map<int, various>;
void
example()
{
map_t dict;
//dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);
//dict.try_emplace(1, {1, 2});
}
Run Code Online (Sandbox Code Playgroud)
但这些选项都不起作用.
使用clang ++我得到这样的错误.(版本:clang版本5.0.1(标签/ RELEASE_501/final))
/opt/local/libexec/llvm-5.0/include/c++/v1/tuple:1365:7: error: no matching
constructor for initialization of 'various'
second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### ... many lines ...
mcve.cpp:14:7: note: in instantiation of …Run Code Online (Sandbox Code Playgroud)