可以使用std::set_intersection
来解决问题:
template<class It>
class Key_iterator {
public:
Key_iterator(It it) : it_(it) {}
Key_iterator& operator++() {
++it_;
return *this;
}
bool operator==(const Key_iterator& other) const {
return it_ == other.it_;
}
bool operator!=(const Key_iterator& other) const {
return it_ != other.it_;
}
auto operator*() const {
return it_->first;
}
private:
It it_;
};
std::map<std::string, int> m1{{"n1", 1}, {"n2", 2}, {"n3", 3}};
std::map<std::string, int> m2{{"n2", 3}, {"n4", 2}, {"n1", 9}};
std::vector<std::string> s;
std::set_intersection(Key_iterator(m1.begin()), Key_iterator(m1.end()),
Key_iterator(m2.begin()), Key_iterator(m2.end()), std::back_inserter(s));
std::set_intersection
需要对两个范围进行排序,而std::map
会按照键的顺序进行排序,因此它们非常匹配。
如果Boost可用,则无需编写Key_iterator
适配器。使用boost::transform_iterator
,可以简化此代码:
std::map<std::string, int> m1{{"n1", 1}, {"n2", 2}, {"n3", 3}};
std::map<std::string, int> m2{{"n2", 3}, {"n4", 2}, {"n1", 9}};
auto key_iterator = [](auto it) {
return boost::transform_iterator(it, [](auto& p) { return p.first; });
};
std::vector<std::string> s;
std::set_intersection(key_iterator(m1.begin()), key_iterator(m1.end()),
key_iterator(m2.begin()), key_iterator(m2.end()), std::back_inserter(s));
std::transform
和std::erase_if
结合起来使用,如果你不想直接使用循环的话。但更高效的方法是使用可能重复的问题的被接受答案。 - t.niese