假设我有两张地图:
typedef int Id;
std::map<Id, std::string> idToStringMap;
std::map<Id, double> idToDoubleMap;
让我们说我想对两张地图的按键进行设定操作。 有没有比创建自定义“插入器”迭代器更简单的方法呢?这样我可以做类似的事情:
std::set<Id> resultSet;
set_difference( idToStringMap.begin(), idToStringMap.end(),
idToDoubleMap.begin(), idToDoubleMap.end(), resultSet.begin() );
我的实验结果意味着有必要创建一个自定义插入器,也许还需要一个自定义键比较器来执行此操作,但在此之前我想要一些见解/快捷方式。
答案 0 :(得分:1)
我不认为只使用没有自定义迭代器的stl就可以实现。您应该创建一个通用的select_1st_iterator
。这会将任何迭代器包装成一对,并在取消引用时首先返回itr-&gt;。
注意:stl的一些扩展有一个select1st
仿函数,它接受一对并返回第一个元素。但我还没有看到迭代器版本。
如果您打算编写迭代器,我建议您使用boost iterator library。 select_1st_iterator
最有可能的候选人是transfor_iterator
假设select_1st_iterator
是一个创建真实select_1st_iterator_t
类型的函数,它可能看起来像:
注意:如果您不使用resultSet
template<class T>
select_1st_iterator_t<T> select_1st_iterator<T>(itr)
{
return select_1st_iterator_t<T>(itr);
}
std::set<Id> resultSet;
set_difference(
select_1st_iterator(idToStringMap.begin()),
select_1st_iterator(idToStringMap.end()),
select_1st_iterator(idToDoubleMap.begin()),
select_1st_iterator(idToDoubleMap.end()),
std::inserter(resultSet, resultSet.begin()) );
{{1}}
答案 1 :(得分:1)
我的解决方案使用了iain的建议:
template <typename T>
class Select1st
: public std::unary_function<T&,typename T::first_type>
{
public:
int operator() (T & value) const
{
return value.first;
}
};
template <typename T>
class KeyGrabItorAdapter
: public boost::transform_iterator< Select1st<typename T::value_type>,
typename T::iterator >
{
public:
KeyGrabItorAdapter( typename T::iterator itor )
: boost::transform_iterator<Select1st<typename T::value_type>,
typename T::iterator>
( itor, Select1st<typename T::value_type>() )
{
}
};
具有以下内容允许以下内容:
typedef std::map<int, int> IntToIntMap;
IntToIntMap intToIntMapA;
IntToIntMap intToIntMapB;
typedef std::map<int, double> IntToDoubleMap;
IntToDoubleMap intToDoubleMapA;
IntToDoubleMap intToDoubleMapB;
KeyGrabItorAdapter<IntToIntMap> grabFirstABegin( intToIntMapA.begin() ) ;
KeyGrabItorAdapter<IntToIntMap> grabFirstAEnd( intToIntMapA.end() ) ;
KeyGrabItorAdapter<IntToDoubleMap> grabFirstBBegin( intToDoubleMapB.begin() ) ;
KeyGrabItorAdapter<IntToDoubleMap> grabFirstBEnd( intToDoubleMapB.end() ) ;
std::set<int> intResultSet;
set_difference( grabFirstABegin, grabFirstAEnd,
grabFirstBBegin, grabFirstBEnd,
inserter( intResultSet, intResultSet.begin()),
intToIntMapA.key_comp() );