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.kstd::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
中,并且重新平衡自己时,键会被复制,旧的键会被销毁。标准能保证不会发生这种情况吗?