使用 interval_map 和封闭边界提升自定义间隔

del*_*ium 5 c++ boost

我正在尝试使用boost::icl::interval_map自定义间隔MyInterval和封闭边界 ( interval_bounds::static_closed),类似于interval_set example。但是,此构造会引发以下错误:

---- Map State -----------------
[0,10] - A

prog.exe: /opt/wandbox/boost-1.71.0/gcc-head/include/boost/icl/interval_base_map.hpp:557: boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::iterator boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::gap_insert(boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::iterator, const interval_type&, const codomain_type&) [with Combiner = boost::icl::inplace_plus<std::__cxx11::basic_string<char> >; SubType = boost::icl::interval_map<int, std::__cxx11::basic_string<char>, boost::icl::partial_absorber, std::less, boost::icl::inplace_plus, boost::icl::inter_section, MyInterval>; DomainT = int; CodomainT = std::__cxx11::basic_string<char>; Traits = boost::icl::partial_absorber; Compare = std::less; Combine = boost::icl::inplace_plus; Section = boost::icl::inter_section; Interval = MyInterval; Alloc = std::allocator; boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::iterator = std::_Rb_tree<MyInterval, std::pair<const MyInterval, std::__cxx11::basic_string<char> >, std::_Select1st<std::pair<const MyInterval, std::__cxx11::basic_string<char> > >, boost::icl::exclusive_less_than<MyInterval>, std::allocator<std::pair<const MyInterval, std::__cxx11::basic_string<char> > > >::iterator; boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::interval_type = MyInterval; boost::icl::interval_base_map<SubType, DomainT, CodomainT, Traits, Compare, Combine, Section, Interval, Alloc>::codomain_type = std::__cxx11::basic_string<char>]: Assertion `this->_map.find(inter_val) == this->_map.end()' failed.
Run Code Online (Sandbox Code Playgroud)

我注意到(1)使用另一种interval_bounds类型,例如static_open,或(2)使用 default interval_type,即interval<int>::closed(),工作得很好。使用MyIntervalstatic_closed边界组合似乎是问题所在。我缺少什么配置或我做错了什么?

代码:下面或Wandbox

提升: 1.71

海湾合作委员会: 9.2.0。

我的间隔.hxx

#ifndef MY_INTERVAL_HXX
#define MY_INTERVAL_HXX

#include <iostream>
#include <boost/icl/interval_map.hpp>

using namespace std;
using namespace boost::icl;

class MyInterval
{
public:
  MyInterval(): _first(), _past(){}
  MyInterval(int lo, int up): _first(lo), _past(up){}
  int first()const{ return _first; }
  int past ()const{ return _past; }
private:
  int _first, _past;
};


namespace boost { namespace icl
{
  template<>
  struct interval_traits<MyInterval>
  {
    typedef MyInterval           interval_type;
    typedef int                  domain_type;
    typedef std::less<int>       domain_compare;

    static interval_type construct(const domain_type &lo, const domain_type &up)
    { return interval_type(lo, up); }

    static domain_type lower(const interval_type &inter_val) { return inter_val.first(); }
    static domain_type upper(const interval_type &inter_val) { return inter_val.past(); }
  };

  template<>
  struct interval_bound_type<MyInterval>
  {
    typedef interval_bound_type type;
    BOOST_STATIC_CONSTANT(bound_type, value = interval_bounds::static_closed);
  };
}} // namespace boost icl

#endif

Run Code Online (Sandbox Code Playgroud)

主文件

#include <iostream>
#include <cstdlib>
#include <string>
#include <boost/icl/interval_map.hpp>
#include "MyInterval.hxx"

using namespace boost::icl;

int main()
{
    interval_map <int
      , std::string
      , partial_absorber
      , std::less // ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, int),
      , inplace_plus // ICL_COMBINE_INSTANCE(inplace_plus, int),
      , inter_section // ICL_SECTION_INSTANCE(inter_section, int),
      , MyInterval
      > imap;

    std::string A("A");
    std::string B("B");
    std::string C("C");
    auto Ai = MyInterval(0,10);
    //auto Ai = interval<int>::closed(0,10);
    auto Bi = MyInterval(5,15);
    //auto Bi = interval<int>::closed(5,15);
    auto Ci = MyInterval(7,12);
    //auto Ci = interval<int>::closed(7,12);

    imap += std::make_pair(Ai, A);
    std::cout << "---- Map State -----------------" << std::endl;
    for (const auto& val : imap) { std::cout << val.first << " - " << val.second << std::endl; }
    std::cout << std::endl;

    imap += std::make_pair(Bi, B);
    std::cout << "---- Map State -----------------" << std::endl;
    for (const auto& val : imap) { std::cout << val.first << " - " << val.second << std::endl; }
    std::cout << std::endl;

    imap += std::make_pair(Ci, C);
    std::cout << "---- Map State -----------------" << std::endl;
    for (const auto& val : imap) { std::cout << val.first << " - " << val.second << std::endl; }
    std::cout << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

预期产出

---- Map State -----------------
[0,10] - A

---- Map State -----------------
[0,5) - A
[5,10] - AB
(10,15] - B

---- Map State -----------------
[0,5) - A
[5,7) - AB
[7,10] - ABC
(10,12] - BC
(12,15] - B
Run Code Online (Sandbox Code Playgroud)

mhb*_*kes 5

我的一个朋友曾经遇到过同样的问题。

问题是您的自定义类的默认构造函数不正确。我不确定boost文档是否说明了这一点,但它必须产生一个无效的范围。在您的情况下,默认构造函数正在生成 range [0, 0]

基本上,库检查范围是否有效的方式是基于边界的类型:

  • 如果是static_open,例如检查区间是否无效的函数等价于upper() <= lower()。这就是为什么它在你的代码:0 <= 0 -> true
  • 对于static_closed,检查区间是否无效的函数等价于upper() < lower()

为了使其工作,您需要更改默认构造函数以生成 where upper() < lower()

TL; 博士

将默认构造函数更改为以下内容:

MyInterval() : _first(0), _past(-1) {}
Run Code Online (Sandbox Code Playgroud)

  • 这是一些高质量的内容。非常感谢分享稀缺经验! (2认同)