首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用interval_map和闭界提升自定义间隔

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

Stack Overflow用户
提问于 2020-04-23 19:06:07
回答 1查看 347关注 0票数 5

我试图使用带有自定义区间boost::icl::interval_map和封闭边界(interval_bounds::static_closed)的MyInterval,类似于interval_set 示例。但是,此构造抛出以下错误:

代码语言:javascript
运行
复制
---- 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.

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

代码:下面或魔盒

Boost: 1.71

GCC: 9.2.0。

MyInterval.hxx

代码语言:javascript
运行
复制
#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

Main.cxx

代码语言:javascript
运行
复制
#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;
}

预期产出

代码语言:javascript
运行
复制
---- 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-23 20:37:35

这也是我一个朋友曾经遇到的问题。

问题是您的自定义类的默认构造函数不正确。我不确定boost文档是否这么说,但它必须产生无效的范围。在您的示例中,默认构造函数正在生成范围[0, 0]

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

  • 如果是static_open,例如,检查间隔是否无效的函数等效于upper() <= lower()。这就是它在您的代码中工作的原因:0 <= 0 -> true
  • 对于static_closed,检查间隔是否无效的函数等效于upper() < lower()

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

TL;DR

将默认构造函数更改为如下所示:

代码语言:javascript
运行
复制
MyInterval() : _first(0), _past(-1) {}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61395092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档