Boost.ICLinterval_map
有两种行为:+=
和. insert
两者在不同的上下文中都很有用。第一个将两个现有区间的公共交点处的值相加。第二个只是在先前未分配的间隔中引入新值(在先前分配的间隔中保留该值)。
但是,我需要一种略有不同的行为,这样,在下面的示例中,我没有得到不想要的区间图(1.,2.)->1 , (2.5,3.)->3, (3.,5.)->2
,而是得到了期望的(1.,2.)->1 , (2.5,5.)->3
.
也就是说,新插入的值替换旧值?我如何声明interval_map
获得这种替换行为?
#include<boost/icl/interval_map.hpp>
int main(){
boost::icl::interval_map<double, int> joined_map;
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(1., 2.),
1
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(3., 5.),
2
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(2.5, 5.),
3
)); // this line doesn't replace the old value 2, it keeps it.
}
奖励:这boost::icl::map
是应该做的吗?我该如何使用它?
编辑 1:这是使用 C++11 的更明确和简化的示例代码
#include<boost/icl/interval_map.hpp>
#include<iostream>
namespace icl = boost::icl;
using interval = icl::interval<double>;
int main(){
icl::interval_map<double, int> joined_map;
joined_map.insert({interval::open(1., 2.), 1});
joined_map.insert({interval::open(3., 5.), 2});
joined_map.insert({interval::open(2.5, 5.), 3});
// ^^^^ this line doesn't replace the old value 2! it keeps it.
for(auto e: joined_map) std::cout << e.first <<' '<< e.second <<'\n';
// prints: (1,2) 1 \\ (2.5,3] 3 \\ (3,5) 2
// desired: (1,2) 1 \\ (2.5,5] 3 // value 2 gone
}
编辑 2: 基于@JorgeBellon 的回答的完整解决方案:
#include<boost/icl/interval_map.hpp>
#include<iostream>
namespace icl = boost::icl;
template <class Type>
struct inplace_replace{// : icl::identity_based_inplace_combine<Type>{
using first_argument_type = Type;
void operator()(Type& object, Type const& operand) const{object = operand;}
};
using interval = icl::interval<double>;
int main(){
icl::interval_map<
double, int,
icl::partial_enricher, // Unmapped intervals have unkown value;
// store identity values
std::less , // Comparator
inplace_replace //, // Combination operator // IMPORTANT!!
// icl::inplace_erasure//, // Extraction operator
// closed_interval<unsigned, std::less> // Interval type
> joined_map;
joined_map.add({interval::open(1. , 2.), 1}); // or joined_map+=std::make_pair(...)
joined_map.add({interval::open(3. , 5.), 2}); // IMPORTANT: USE add, NOT insert!!
joined_map.add({interval::open(2.5, 5.), 3});
// ^^^^ this line now replaces the old value 2
for(auto e: joined_map) std::cout << e.first <<' '<< e.second <<'\n';
// prints: (1,2) 1 \\ (2.5,5] 3 // value 2 gone
}