C++ 如何将所有对从一个std::map移动到另一个std::map

C++ 如何将所有对从一个std::map移动到另一个std::map,c++,stl,c++11,C++,Stl,C++11,假设我有以下几点: std::map<KEY,VALUE> m1; std::map<KEY,VALUE> m2; Joachim Pileborg的建议仅在m2和m1不具有相同密钥时有效(即m2的值不会被相同密钥的m1的值覆盖) 怎么样?最明显的解决方案就是自己编写一个循环: for ( std::map<KEY, VALUE>::const_iterator current = m1.begin(); current != m1.end(

假设我有以下几点:

std::map<KEY,VALUE> m1;
std::map<KEY,VALUE> m2;
Joachim Pileborg的建议仅在m2和m1不具有相同密钥时有效(即m2的值不会被相同密钥的m1的值覆盖)


怎么样?

最明显的解决方案就是自己编写一个循环:

for ( std::map<KEY, VALUE>::const_iterator current = m1.begin();
        current != m1.end();
        ++ current ) {
    m2[current->first] = current->second;
}
这并不完全是直观的,如果没有它,我会犹豫使用它 评论,因为:

  • 由于
    std::map
    没有
    push\u back
    push\u front
    ,您需要 要使用更通用的
    指令
    ,则需要一个迭代器 指定插入的位置。除了
    std::map
    将此迭代器视为“提示”,因为它通常不会是 很好的提示,它将被忽略

  • 实际上,您必须从
    m2
    复制到
    m1
    ,因为插入到 map不会覆盖任何现有值,并且当存在键时 在这两个映射中,您都希望保留
    m1
    中的值


  • 是否允许元素副本?或者你的字面意思是语言意义上的“移动”?就是在这样的时候,你才会真正欣赏
    list::splice
    。想想看,非常令人惊讶的是,关联容器没有接口来交换它们的节点。
    std::move(m1.begin(),m1.end(),std::inserter(m2,m2.begin())
    似乎起到了作用-但不确定m1和m2中存在的密钥。需要验证。看起来如果m1和m2中存在密钥,m2的密钥对将不会被m1中的密钥对覆盖…这里实际可用吗?
    std::move
    我没有使用它的经验,但IIUC会导致修改源元素。这,如果这些元素位于
    std::map
    中,则会导致未定义的行为。@JamesKanze没有UB。关键部分是复制的,因为它是常量限定的。但是使用
    inserter
    它不会覆盖。假设建议是
    m2=std::move(m1)
    这会破坏
    m2
    以前的任何内容,而不是合并
    m1
    中的值。OP希望
    m2
    保留未被
    m1
    覆盖的任何原始内容+1这看起来不错-你的观点2.是为什么std::move()的关键,本身不足以满足我的要求-tydos
    m2[std::move(current->first)]=std::move(current->second);
    在这种情况下可以避免一些复制?(例如,如果键和值是std::string)@ThomasPetit:您可以移动
    ,但不能移动
    第一个
    ,因为映射键是不可变的。@ThomasPetit通过在表达式中的任何位置添加
    移动
    ,来更改一个简单表达式,例如
    m2[current->first]=current->second;
    ,这是过早的优化。请保持简单(在这种情况下,也要保持它的便携性),直到分析器说你别无选择。
    std::move( m1.begin(), m1.end(), std::inserter( m2, m2.begin() ));
    
    for ( std::map<KEY, VALUE>::const_iterator current = m1.begin();
            current != m1.end();
            ++ current ) {
        m2[current->first] = current->second;
    }
    
    std::copy( m2.begin(), m2.end(), std::inserter( m1, m1.end() ) );
    m2.clear();
    m2.swap( m1 );