C++ std::map value对象能否包含对相应键的引用?
本质上,我希望C++ std::map value对象能否包含对相应键的引用?,c++,stl,C++,Stl,本质上,我希望值对象维护对相应键对象的引用,因为其中包含一些有用的信息,通过值对象访问这些信息会很好 我试图做的可能只是没有意义,但考虑以下: class key { // ... Various members ... friend bool operator< (const key &lhs, const key &rhs) { /* ... */ } }; class value { public: value(const key &
值
对象维护对相应键
对象的引用,因为其中包含一些有用的信息,通过值
对象访问这些信息会很好
我试图做的可能只是没有意义,但考虑以下:
class key
{
// ... Various members ...
friend bool operator< (const key &lhs, const key &rhs) { /* ... */ }
};
class value
{
public:
value(const key &k) : k(k) {}
private:
const key &k;
// ... Various members ...
};
std::map<key,value> m;
// start a new scope, which may be due to e.g. function call, loop, etc.
{
key k; // I'm on the stack!
m.insert(std::pair<key,value>(k, value(k)));
}
类密钥
{
//……各位成员。。。
friend bool运算符<(常数键和lhs、常数键和rhs){/*…*/}
};
阶级价值
{
公众:
值(常数键&k):k(k){}
私人:
康斯特基和k;
//……各位成员。。。
};
std::map m;
//启动一个新的作用域,这可能是由于函数调用、循环等引起的。
{
k键;//我在堆栈上!
m、 插入(标准::对(k,值(k));
}
当然,这不起作用,因为这是对堆栈对象的引用,只要
k
超出范围,堆栈对象就会中断。是否有某种方法可以获取对映射中维护的密钥副本的引用?为什么不引用value成员作为密钥
class key { friend bool operator< (const key &,const key&); }
class value {
public:
value(const key &k) : k(k) {}
const key &key() const {return k};
private:
key k;
}
std::map<key,value> m;
key k;
value v(k);
m.insert(std::pair<key,value>(v.key(),v));
类键{friend bool操作符<(常数键&,常数键&);}
阶级价值{
公众:
值(常数键&k):k(k){}
const key&key()const{return k};
私人:
键k;
}
std::map m;
键k;
v(k)值;
m、 插入(std::pair(v.key(),v));
。。。或者类似的。似乎在值对象内部构造键通常会更容易
更像:
#include <map>
#include <iostream>
struct key {
key(unsigned int ik) : k(ik) {}
unsigned int k;
friend bool operator< (const key &,const key &);
};
bool operator< (const key &me,const key &other) {return me.k < other.k;}
struct value {
value(unsigned int ik, unsigned int iv) : k(ik), v(iv) {}
const key &theKey() const {return k;}
unsigned int v;
key k;
};
int main() {
std::map<key,value> m;
value v(1,3);
m.insert(std::pair<key,value>(v.theKey(),v));
for(std::map<key,value>::iterator it=m.begin(); it!=m.end();++it)
std::cout << it->second.theKey().k << " " << it->second.v << "\n";
return 0;
}
#包括
#包括
结构键{
关键帧(无符号整数ik):k(ik){}
无符号整数k;
友元布尔运算符<(常数键和,常数键和);
};
布尔运算符<(常量键和me,常量键和其他){return me.k std::cout second.theKey().k插入后可以将引用放置到位,但必须将其设置为指针:
std::map<key, value>::iterator iter = m.insert(std::make_pair(k, v)).first;
iter->second.setValue(&iter->first);
std::map::iterator iter=m.insert(std::make_pair(k,v))。首先;
iter->second.setValue(&iter->first);
你为什么需要这样做?你总是可以将密钥和值一起传递。@KennyTM:我可以,但在我可能需要的任何地方传递例如std::pair
似乎都是一件非常痛苦的事情。我希望会有更优雅的东西(例如,使用等效的Java不会有问题)@Oli:通常你会得到一个std::pair
,因为map
的迭代器的value\u type
是std::pair
。如果你的键和值关系如此密切,那么一个集合可能更合适。@Kenny:我理解(事实上我忘了map的迭代器在pair
上工作)。但是如果隔离的值
可以封装我需要的所有东西,那就更干净了。(就像我说的,这在Java这样的语言中是微不足道的…)我试图避免再复制k
,因为它可能相当重(我知道这可能是设计不好的标志)。但除此之外,我认为这是可行的。仅供参考:最后一行也可以是m.insert(std::pair(k,v));
。如果可能,我认为最好是在值之外生成键值(可能在构造函数中),我上面的代码已经完成了一半。@jkerian:我做不到你的第二个代码片段中的内容。在我的现实世界中,我从别处得到了一个键
对象,然后我需要创建(或定位)映射中的值
对象。简言之:首先创建键
。嗯……也许我误解了。键消失的问题(在这种情况下是堆栈外的问题)真正问题的一部分?或者这个示例代码的一部分?如果它是真正代码的一部分,你能说服你的密钥源切换到智能指针吗?如果不是,你只需要复制它。另一个解决方案。如果我理解正确,你需要在地图中再次查找该项时访问该密钥?如果是,不会简单使用std::map::find work?返回的迭代器将包含->first参数。有趣的是,我想接下来的问题是:*(&iter->first)的生存期是多少保证与m
的长度一样长?是的,它是,或者至少与m中的条目持续时间一样长。如果从映射中删除条目,则整个内容都会被释放,包括值。但是,您可能无法从值析构函数中获取密钥。您说您从其他地方获取密钥;请注意,将密钥放入映射中的对象复制它,因为映射将实际数据存储在其树节点中,而不仅仅是指针。当然,您可以定义一个类型,该类型只保存指针或引用,并在必要时传递比较。此外,从技术上讲,我想您可能只能保证迭代器本身保持有效,但我认为几乎所有校勘在某种程度上满足了这一要求,同时保留了键和值的地址。@沃尔特:我担心,当一个人把更多的项放入m
中,并且重新平衡自己时,键会被复制,旧的键会被销毁。标准能保证不会发生这种情况吗?